NVIDIA cuML: two paths to GPU machine learning, and where each one breaks
NVIDIA cuML: GPU-Accelerated Machine Learning
At a glance
- What is it?
- cuML ships a GPU-native estimator library and a drop-in accelerator for existing scikit-learn, UMAP and HDBSCAN code. The interesting engineering question is not speed but which of the two paths a codebase can actually take.
- Who is it for?
- Adopt cuML if your pipeline already runs on NVIDIA GPUs and your hot path is clustering, dimensionality reduction or a supported estimator at a scale where CPU execution is the bottleneck; the cuml.accel path is the lower-risk entry because unaccelerated calls fall back to the CPU implementation instead of failing. Do not adopt it as a general NumPy or pandas replacement, and do not expect cuml.dask to cover every estimator in the single-GPU API.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
Two entry points, two different migration costs
cuML is not one library with one interface. The README describes two ways to run machine learning on NVIDIA GPUs, and they impose very different amounts of work on an existing codebase.
The first is the cuml Python API. It follows the scikit-learn fit-predict-transform pattern, but imports come from cuml rather than sklearn. The README's example imports make_blobs from cuml.datasets and DBSCAN from cuml.cluster, builds a model with eps=1.0 and min_samples=5, calls fit, and reads labels_ off the fitted object. That is a source-level change in every file that touches the estimator.
The second is cuml.accel, which the README describes as accelerating existing scikit-learn, UMAP and HDBSCAN code without changing the Python code that uses those libraries. Here the estimator imports stay as they are. The change moves to how the process starts.
That distinction is the whole adoption decision. The cuml API gives direct control over machine learning workflows, in the README's phrasing, and assumes you are willing to own GPU-specific imports and data placement. cuml.accel assumes you are not, and accepts the coverage limits that come with interception.
What cuml.accel intercepts, and what it silently leaves on the CPU
The accelerator is loaded at process or session level. From the command line, the README gives python -m cuml.accel script.py. In a Jupyter notebook, the equivalent is the magic %load_ext cuml.accel, loaded before importing scikit-learn, UMAP or HDBSCAN. Order matters here: the extension has to be in place before those imports resolve, which is why the README states the ordering explicitly.
The fallback rule is the part worth reading twice. Supported operations run on the GPU. When an estimator or configuration cannot be accelerated, cuml.accel uses the original CPU implementation so the rest of the workflow can continue. This is a deliberate design choice and it cuts both ways. A pipeline that mixes a supported clustering step with an unsupported preprocessing step will still complete, which makes the migration low risk. It will also complete without telling you, unless you ask. The README points at logging and profiling tools for checking which operations ran on the GPU, and at the cuml.accel compatibility page for current coverage and fallback conditions.
If you skip that check, you can end up with a workflow that looks migrated and runs mostly on the CPU. The fallback is silent by default, so the compatibility page and the profiling output are the only reliable record of what actually moved.
Getting it installed: the selector, not a pinned command
The README does not print an install command. It directs you to the RAPIDS installation selector to generate one for nightly or release cuML packages, with conda, pip or Docker as the delivery mechanism. That is a deliberate omission: the correct package name and channel depend on your CUDA version, Python version and platform combination, and a hardcoded example in the README would go stale faster than the selector would.
Two version constraints are stated. cuML is compatible with scikit-learn version 1.6 or higher. The current release line is 26.08, with v26.08.00 published on 2026-08-05, following v26.06.00 and v26.04.00 on a roughly two-month cadence. Source builds are possible and are covered in BUILD.md rather than the README.
For the accelerator path there is nothing to configure beyond the launch form. python -m cuml.accel script.py needs no config key, no environment variable and no registration step. That is the entire setup surface, and it is the strongest argument for trying this path before rewriting imports.
The 50x figure and what it does not tell you
The README states that on representative benchmarks cuML can accelerate scikit-learn workflows by up to 50x, and immediately qualifies it: performance depends on the algorithm, dataset and hardware. It links to the cuML benchmarks page for results and methodology. Treat the number as a pointer to that methodology page rather than as a planning input. A best-case figure across a benchmark suite says nothing about your estimator on your data shape.
The GPU-native API has its own cost profile that the benchmark framing tends to hide. Data and computation stay on the GPU, per the README, which is where the speed comes from. It is also where the friction comes from: data has to get to the device and results have to come back, and any step in your pipeline that is not GPU-resident becomes a transfer boundary. The README's example is self-contained, generating blobs with make_blobs and clustering them without leaving the device. Real pipelines rarely look like that.
cuml.dask covers selected algorithms, not all of them
For work that exceeds one GPU, the README describes the cuml.dask API as providing distributed implementations of selected algorithms for multi-GPU and multi-node execution with Dask, and points to the multi-GPU guide for cluster setup, supported algorithms and examples.
The word selected is doing real work in that sentence. The single-GPU cuml API covers clustering, dimensionality reduction, regression, classification, preprocessing, model selection, time series, model explanation and nearest-neighbor workflows, per the README. The Dask surface is narrower, and the README does not enumerate it. If your plan assumes that anything in the cuml API scales out by swapping the import for a Dask variant, verify against the multi-GPU guide first. Dask also brings its own cluster setup and scheduling concerns, which is a different operational commitment from running a single process on one GPU.
Serialisation, cloudpickle and the one security instruction in the README
cuML models can be serialised with pickle or joblib and loaded later for inference. The README notes that cuML uses cloudpickle so that models trained with cuml.accel can be loaded and used with scikit-learn. That detail matters for teams running the accelerator path: a model produced under acceleration is not trapped in a cuML-only loading path.
The README then states, in bold, that only trusted sources should be unpickled, that pickle and joblib are not secure, and that malicious payloads can execute arbitrary code during deserialisation. It names pickle.load, pickle.loads, joblib.load and any file-based model loading as in scope. This is not cuML-specific behaviour; it is the standard pickle contract, and the README is right to repeat it. If model artefacts move between environments or pass through shared storage, that is a boundary to think about before it becomes a load path.
Licensing is Apache-2.0, which is permissive and includes an explicit patent grant. That is a statement about the licence text, not legal advice about your situation.
Where cuML is the wrong tool
If your workloads run on CPU-only machines, cuML has nothing to offer. Both paths assume NVIDIA GPUs. There is no CPU execution mode described in the README; the fallback in cuml.accel exists to keep a workflow running, not to serve as a supported CPU backend.
If your pipeline is dominated by operations outside the supported estimator set, the accelerator will fall back and you will pay the interception cost for no GPU work. That is the failure mode to watch for: a successful run that is functionally a CPU run.
If you need a distributed implementation of an algorithm that only exists in the single-GPU API, cuml.dask will not help, because the README describes it as covering selected algorithms.
And if your team cannot absorb GPU dependency management, the installation selector's range of conda, pip and Docker options is a sign of how many combinations exist. That is ongoing operational cost, not a one-time setup step.
The alternative: staying on scikit-learn, and what changes if you do
The obvious alternative is plain scikit-learn on CPU, and the difference is architectural rather than a matter of degree. scikit-learn executes on the CPU with no device-placement decisions in your code. cuML's native API moves the estimator itself to the GPU, which means data and computation stay on the device and your pipeline inherits the transfer boundaries that come with that. The cuml.accel path sits between the two: your code stays scikit-learn-shaped, and the runtime decides per call whether to accelerate or fall back.
Choosing scikit-learn means giving up the acceleration and keeping the simpler dependency story, with no CUDA version to match and no GPU to provision. Choosing cuML means the reverse. The interesting middle case is a team that wants the cuml.accel path precisely because the fallback makes partial migration survivable, and is willing to read the compatibility page to know which parts of its pipeline actually moved.
Editorial conclusion
Adopt cuML if your pipeline already runs on NVIDIA GPUs and your hot path is clustering, dimensionality reduction or a supported estimator at a scale where CPU execution is the bottleneck; the cuml.accel path is the lower-risk entry because unaccelerated calls fall back to the CPU implementation instead of failing. Do not adopt it as a general NumPy or pandas replacement, and do not expect cuml.dask to cover every estimator in the single-GPU API. Before committing, run your own script under python -m cuml.accel with the logging and profiling tools enabled and read the compatibility page, because the fallback list, not the benchmark table, determines whether the migration is a one-line change or a partial rewrite.
Community notes