Skill Tracer
Skills › Scientific Agent Skills › optimize-for-gpu › cuml.md

cuml.md

721 lines · skills/optimize-for-gpu/references/cuml.md at 5f2bc03

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1# cuML Reference
2
3> Review: 2026-10-01. Code below is illustrative unless explicitly described as CPU-tested.
4> GPU execution, performance, GDS, and multi-GPU behavior require validation on target hardware.
5
6cuML is NVIDIA's GPU-accelerated machine learning library within the RAPIDS ecosystem. It
7provides scikit-learn-compatible APIs for classification, regression, clustering, dimensionality
8reduction, preprocessing, and model selection. Performance depends on algorithm, shape, dtype,
9fallback behavior, and transfer cost; benchmark the complete pipeline on representative data.
11> **Full documentation:** https://docs.nvidia.com/cuml/26.08/

cuML Reference

Review: 2026-10-01. Code below is illustrative unless explicitly described as CPU-tested. GPU execution, performance, GDS, and multi-GPU behavior require validation on target hardware.

cuML is NVIDIA's GPU-accelerated machine learning library within the RAPIDS ecosystem. It provides scikit-learn-compatible APIs for classification, regression, clustering, dimensionality reduction, preprocessing, and model selection. Performance depends on algorithm, shape, dtype, fallback behavior, and transfer cost; benchmark the complete pipeline on representative data.

Full documentation: https://docs.nvidia.com/cuml/26.08/
Raw lines 1 to 12
13## Table of Contents
151. [Installation and Setup](#installation-and-setup)
162. [Two Usage Modes](#two-usage-modes)
173. [cuml.accel Accelerator Mode](#cumlaccel-accelerator-mode)
184. [Direct cuML API](#direct-cuml-api)
195. [Algorithm Catalog](#algorithm-catalog)
206. [Input/Output Type Handling](#inputoutput-type-handling)
217. [Preprocessing](#preprocessing)
228. [Feature Extraction](#feature-extraction)
239. [Model Selection and Tuning](#model-selection-and-tuning)
2410. [Forest Inference Library (FIL)](#forest-inference-library)
2511. [Multi-GPU with Dask](#multi-gpu-with-dask)
2612. [Model Serialization](#model-serialization)
2713. [Memory Management](#memory-management)
2814. [Performance Optimization](#performance-optimization)
2915. [Interoperability](#interoperability)
3016. [Key Differences from sklearn](#key-differences-from-sklearn)
3117. [Common Migration Patterns](#common-migration-patterns)
33---

Table of Contents

  1. Installation and Setup
  2. Two Usage Modes
  3. cuml.accel Accelerator Mode
  4. Direct cuML API
  5. Algorithm Catalog
  6. Input/Output Type Handling
  7. Preprocessing
  8. Feature Extraction
  9. Model Selection and Tuning
  10. Forest Inference Library (FIL)
  11. Multi-GPU with Dask
  12. Model Serialization
  13. Memory Management
  14. Performance Optimization
  15. Interoperability
  16. Key Differences from sklearn
  17. Common Migration Patterns

Raw lines 13 to 34
35## Installation and Setup
37Use `uv add` in standalone examples; follow the user's existing project package manager when one
38is already configured.
40```bash
41uv add "cuml-cu12==26.8.*" # For CUDA 12.x
42uv add "cuml-cu13==26.8.*" # For CUDA 13.x
43```
45cuML wheels are published directly to PyPI (since RAPIDS 25.10) — the `--extra-index-url=https://pypi.nvidia.com` extra index is no longer required.
47**Platform:** Linux and WSL2 only (no native macOS or Windows).
48**Requires:** Python >= 3.11, scikit-learn >= 1.6, NVIDIA GPU with CUDA 12.x or 13.x support.
50Verify:
51```python
52import cuml
53print(cuml.__version__)
55from cuml.datasets import make_blobs
56X, y = make_blobs(n_samples=1000, n_features=10)
57print(f"Generated {X.shape[0]} samples on GPU")
58```
60---

Installation and Setup

Use uv add in standalone examples; follow the user's existing project package manager when one is already configured.

uv add "cuml-cu12==26.8.*"    # For CUDA 12.x
uv add "cuml-cu13==26.8.*"    # For CUDA 13.x

cuML wheels are published directly to PyPI (since RAPIDS 25.10) — the --extra-index-url=https://pypi.nvidia.com extra index is no longer required.

Platform: Linux and WSL2 only (no native macOS or Windows). Requires: Python >= 3.11, scikit-learn >= 1.6, NVIDIA GPU with CUDA 12.x or 13.x support.

Verify:

import cuml
print(cuml.__version__)

from cuml.datasets import make_blobs
X, y = make_blobs(n_samples=1000, n_features=10)
print(f"Generated {X.shape[0]} samples on GPU")

Raw lines 35 to 61
62## Two Usage Modes

Two Usage Modes

Raw lines 62 to 63
64### 1. cuml.accel (Zero-Code-Change)
65Transparently intercepts sklearn, umap-learn, and hdbscan calls and routes them to GPU. Falls back to CPU for unsupported operations. Best for: quick acceleration of existing sklearn code, mixed codebases, prototyping.

1. cuml.accel (Zero-Code-Change)

Transparently intercepts sklearn, umap-learn, and hdbscan calls and routes them to GPU. Falls back to CPU for unsupported operations. Best for: quick acceleration of existing sklearn code, mixed codebases, prototyping.

Raw lines 64 to 66
67### 2. Direct cuML API
68Replace `from sklearn` with `from cuml`. Maximum performance, explicit control over GPU execution. Best for: production pipelines, maximum performance, new GPU-first code.
70---

2. Direct cuML API

Replace from sklearn with from cuml. Maximum performance, explicit control over GPU execution. Best for: production pipelines, maximum performance, new GPU-first code.


Raw lines 67 to 71
72## cuml.accel Accelerator Mode
74The fastest path from sklearn to GPU — no code changes required. Similar to `cudf.pandas` for pandas.

cuml.accel Accelerator Mode

The fastest path from sklearn to GPU — no code changes required. Similar to cudf.pandas for pandas.

Raw lines 72 to 75
76### Activation
78```python
79# Jupyter/IPython (MUST be the first cell, before any sklearn import)
80%load_ext cuml.accel
82import sklearn # Now GPU-accelerated
83from sklearn.cluster import KMeans # Runs on GPU transparently
84```
86```bash
87# Command line
88python -m cuml.accel script.py
89python -m cuml.accel -v script.py # With info logging
90python -m cuml.accel -vv script.py # With debug logging
91```
93```python
94# Programmatic (call BEFORE importing sklearn)
95import cuml
96cuml.accel.install()
98from sklearn.cluster import KMeans # Now GPU-accelerated
99```
101```bash
102# Environment variable
103CUML_ACCEL_ENABLED=1 python script.py
104```

Activation

# Jupyter/IPython (MUST be the first cell, before any sklearn import)
%load_ext cuml.accel

import sklearn  # Now GPU-accelerated
from sklearn.cluster import KMeans  # Runs on GPU transparently
# Command line
python -m cuml.accel script.py
python -m cuml.accel -v script.py     # With info logging
python -m cuml.accel -vv script.py    # With debug logging
# Programmatic (call BEFORE importing sklearn)
import cuml
cuml.accel.install()

from sklearn.cluster import KMeans  # Now GPU-accelerated
# Environment variable
CUML_ACCEL_ENABLED=1 python script.py
Raw lines 76 to 105
Runs code python script.py :103
106### How It Works
108- Intercepts sklearn/umap-learn/hdbscan imports and replaces estimators with GPU versions.
109- If an operation isn't supported on GPU, it silently falls back to CPU sklearn.
110- Uses managed memory by default — host RAM augments GPU VRAM.
111- Models pickled under cuml.accel load as standard sklearn objects in non-GPU environments.
112- Accelerates 30+ algorithms across sklearn, umap-learn, and hdbscan. Recent releases (26.04-26.06) expanded coverage to preprocessing estimators (StandardScaler, MinMaxScaler, MaxAbsScaler, PolynomialFeatures, LabelEncoder) and SpectralClustering.
113- 26.08 requires scikit-learn >=1.6; specific accelerated preprocessors require >=1.8. Check the [26.08 compatibility page](https://docs.nvidia.com/cuml/26.08/cuml-accel/compatibility/) for method and parameter restrictions.

How It Works

  • Intercepts sklearn/umap-learn/hdbscan imports and replaces estimators with GPU versions.
  • If an operation isn't supported on GPU, it silently falls back to CPU sklearn.
  • Uses managed memory by default — host RAM augments GPU VRAM.
  • Models pickled under cuml.accel load as standard sklearn objects in non-GPU environments.
  • Accelerates 30+ algorithms across sklearn, umap-learn, and hdbscan. Recent releases (26.04-26.06) expanded coverage to preprocessing estimators (StandardScaler, MinMaxScaler, MaxAbsScaler, PolynomialFeatures, LabelEncoder) and SpectralClustering.
  • 26.08 requires scikit-learn >=1.6; specific accelerated preprocessors require >=1.8. Check the 26.08 compatibility page for method and parameter restrictions.
Raw lines 106 to 114
115### Known Fallback Triggers (Runs on CPU Instead)
117- Sparse input data (most algorithms)
118- Callable parameters (e.g., callable `init` for KMeans)
119- Certain parameter values: `n_components="mle"` for PCA, `positive=True` for linear models, warm starts
120- Unsupported distance metrics for neighbors algorithms
121- Multi-output targets for Random Forest
122- String/object dtypes — must pre-encode with LabelEncoder first

Known Fallback Triggers (Runs on CPU Instead)

  • Sparse input data (most algorithms)
  • Callable parameters (e.g., callable init for KMeans)
  • Certain parameter values: n_components="mle" for PCA, positive=True for linear models, warm starts
  • Unsupported distance metrics for neighbors algorithms
  • Multi-output targets for Random Forest
  • String/object dtypes — must pre-encode with LabelEncoder first
Raw lines 115 to 123
124### Numerical Precision
126GPU estimators can use different algorithms, solvers, tree-split approximations, defaults, and random streams. Differences can exceed roundoff. Compare held-out quality, prediction agreement, class/feature order and calibration; use sign/subspace-aware checks for decompositions. A matching seed does not imply matching models.
128---

Numerical Precision

GPU estimators can use different algorithms, solvers, tree-split approximations, defaults, and random streams. Differences can exceed roundoff. Compare held-out quality, prediction agreement, class/feature order and calibration; use sign/subspace-aware checks for decompositions. A matching seed does not imply matching models.


Raw lines 124 to 129
130## Direct cuML API
132The API follows fit/predict/transform conventions, but signatures, defaults and supported inputs differ. Consult the chosen estimator before replacing imports.
134```python
135from cuml.cluster import DBSCAN
136from cuml.datasets import make_blobs
138# Create data directly on GPU
139X, y = make_blobs(n_samples=100_000, centers=5, n_features=10, random_state=42)
141# Fit — runs on GPU
142model = DBSCAN(eps=1.0, min_samples=5)
143model.fit(X)
144print(model.labels_)
145```
147```python
148from cuml import LinearRegression
149from cuml.datasets import make_regression
150from cuml.model_selection import train_test_split
152X, y = make_regression(n_samples=100_000, n_features=50, noise=0.1)
153X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
155model = LinearRegression()
156model.fit(X_train, y_train)
157predictions = model.predict(X_test)
158score = model.score(X_test, y_test)
159print(f"R2 score: {score:.4f}")
160```
162---

Direct cuML API

The API follows fit/predict/transform conventions, but signatures, defaults and supported inputs differ. Consult the chosen estimator before replacing imports.

from cuml.cluster import DBSCAN
from cuml.datasets import make_blobs

# Create data directly on GPU
X, y = make_blobs(n_samples=100_000, centers=5, n_features=10, random_state=42)

# Fit — runs on GPU
model = DBSCAN(eps=1.0, min_samples=5)
model.fit(X)
print(model.labels_)
from cuml import LinearRegression
from cuml.datasets import make_regression
from cuml.model_selection import train_test_split

X, y = make_regression(n_samples=100_000, n_features=50, noise=0.1)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

model = LinearRegression()
model.fit(X_train, y_train)
predictions = model.predict(X_test)
score = model.score(X_test, y_test)
print(f"R2 score: {score:.4f}")

Raw lines 130 to 163
164## Algorithm Catalog

Algorithm Catalog

Raw lines 164 to 165
166### Clustering
168| cuML | sklearn Equivalent | Multi-GPU |
169|------|-------------------|-----------|
170| `cuml.KMeans` | `sklearn.cluster.KMeans` | Yes |
171| `cuml.DBSCAN` | `sklearn.cluster.DBSCAN` | Yes |
172| `cuml.AgglomerativeClustering` | `sklearn.cluster.AgglomerativeClustering` | No |
173| `cuml.cluster.hdbscan.HDBSCAN` | `hdbscan.HDBSCAN` | No |
174| `cuml.cluster.SpectralClustering` | `sklearn.cluster.SpectralClustering` | No |

Clustering

cuMLsklearn EquivalentMulti-GPU
cuml.KMeanssklearn.cluster.KMeansYes
cuml.DBSCANsklearn.cluster.DBSCANYes
cuml.AgglomerativeClusteringsklearn.cluster.AgglomerativeClusteringNo
cuml.cluster.hdbscan.HDBSCANhdbscan.HDBSCANNo
cuml.cluster.SpectralClusteringsklearn.cluster.SpectralClusteringNo
Raw lines 166 to 175
176### Regression
178| cuML | sklearn Equivalent | Multi-GPU |
179|------|-------------------|-----------|
180| `cuml.LinearRegression` | `sklearn.linear_model.LinearRegression` | Yes |
181| `cuml.Ridge` | `sklearn.linear_model.Ridge` | Yes |
182| `cuml.Lasso` | `sklearn.linear_model.Lasso` | Yes |
183| `cuml.ElasticNet` | `sklearn.linear_model.ElasticNet` | Yes |
184| `cuml.SVR` | `sklearn.svm.SVR` | No |
185| `cuml.KernelRidge` | `sklearn.kernel_ridge.KernelRidge` | No |
186| `cuml.ensemble.RandomForestRegressor` | `sklearn.ensemble.RandomForestRegressor` | Yes |
187| `cuml.MBSGDRegressor` | `sklearn.linear_model.SGDRegressor` | No |

Regression

cuMLsklearn EquivalentMulti-GPU
cuml.LinearRegressionsklearn.linear_model.LinearRegressionYes
cuml.Ridgesklearn.linear_model.RidgeYes
cuml.Lassosklearn.linear_model.LassoYes
cuml.ElasticNetsklearn.linear_model.ElasticNetYes
cuml.SVRsklearn.svm.SVRNo
cuml.KernelRidgesklearn.kernel_ridge.KernelRidgeNo
cuml.ensemble.RandomForestRegressorsklearn.ensemble.RandomForestRegressorYes
cuml.MBSGDRegressorsklearn.linear_model.SGDRegressorNo
Raw lines 176 to 188
189### Classification
191| cuML | sklearn Equivalent | Multi-GPU |
192|------|-------------------|-----------|
193| `cuml.LogisticRegression` | `sklearn.linear_model.LogisticRegression` | No |
194| `cuml.ensemble.RandomForestClassifier` | `sklearn.ensemble.RandomForestClassifier` | Yes |
195| `cuml.svm.SVC` | `sklearn.svm.SVC` | No |
196| `cuml.svm.LinearSVC` | `sklearn.svm.LinearSVC` | No |
197| `cuml.naive_bayes.GaussianNB` | `sklearn.naive_bayes.GaussianNB` | No |
198| `cuml.naive_bayes.MultinomialNB` | `sklearn.naive_bayes.MultinomialNB` | Yes |
199| `cuml.naive_bayes.BernoulliNB` | `sklearn.naive_bayes.BernoulliNB` | No |
200| `cuml.naive_bayes.CategoricalNB` | `sklearn.naive_bayes.CategoricalNB` | No |
201| `cuml.naive_bayes.ComplementNB` | `sklearn.naive_bayes.ComplementNB` | No |
202| `cuml.neighbors.KNeighborsClassifier` | `sklearn.neighbors.KNeighborsClassifier` | Yes |
203| `cuml.neighbors.KNeighborsRegressor` | `sklearn.neighbors.KNeighborsRegressor` | Yes |
204| `cuml.MBSGDClassifier` | `sklearn.linear_model.SGDClassifier` | No |
205| `cuml.multiclass.OneVsOneClassifier` | `sklearn.multiclass.OneVsOneClassifier` | No |
206| `cuml.multiclass.OneVsRestClassifier` | `sklearn.multiclass.OneVsRestClassifier` | No |

Classification

cuMLsklearn EquivalentMulti-GPU
cuml.LogisticRegressionsklearn.linear_model.LogisticRegressionNo
cuml.ensemble.RandomForestClassifiersklearn.ensemble.RandomForestClassifierYes
cuml.svm.SVCsklearn.svm.SVCNo
cuml.svm.LinearSVCsklearn.svm.LinearSVCNo
cuml.naive_bayes.GaussianNBsklearn.naive_bayes.GaussianNBNo
cuml.naive_bayes.MultinomialNBsklearn.naive_bayes.MultinomialNBYes
cuml.naive_bayes.BernoulliNBsklearn.naive_bayes.BernoulliNBNo
cuml.naive_bayes.CategoricalNBsklearn.naive_bayes.CategoricalNBNo
cuml.naive_bayes.ComplementNBsklearn.naive_bayes.ComplementNBNo
cuml.neighbors.KNeighborsClassifiersklearn.neighbors.KNeighborsClassifierYes
cuml.neighbors.KNeighborsRegressorsklearn.neighbors.KNeighborsRegressorYes
cuml.MBSGDClassifiersklearn.linear_model.SGDClassifierNo
cuml.multiclass.OneVsOneClassifiersklearn.multiclass.OneVsOneClassifierNo
cuml.multiclass.OneVsRestClassifiersklearn.multiclass.OneVsRestClassifierNo
Raw lines 189 to 207
208### Dimensionality Reduction and Manifold Learning
210| cuML | sklearn/Library Equivalent | Multi-GPU |
211|------|---------------------------|-----------|
212| `cuml.PCA` | `sklearn.decomposition.PCA` | Yes |
213| `cuml.IncrementalPCA` | `sklearn.decomposition.IncrementalPCA` | No |
214| `cuml.TruncatedSVD` | `sklearn.decomposition.TruncatedSVD` | Yes |
215| `cuml.UMAP` | `umap.UMAP` | Yes (inference) |
216| `cuml.TSNE` | `sklearn.manifold.TSNE` | No |
217| `cuml.random_projection.GaussianRandomProjection` | `sklearn.random_projection.GaussianRandomProjection` | No |
218| `cuml.random_projection.SparseRandomProjection` | `sklearn.random_projection.SparseRandomProjection` | No |

Dimensionality Reduction and Manifold Learning

cuMLsklearn/Library EquivalentMulti-GPU
cuml.PCAsklearn.decomposition.PCAYes
cuml.IncrementalPCAsklearn.decomposition.IncrementalPCANo
cuml.TruncatedSVDsklearn.decomposition.TruncatedSVDYes
cuml.UMAPumap.UMAPYes (inference)
cuml.TSNEsklearn.manifold.TSNENo
cuml.random_projection.GaussianRandomProjectionsklearn.random_projection.GaussianRandomProjectionNo
cuml.random_projection.SparseRandomProjectionsklearn.random_projection.SparseRandomProjectionNo
Raw lines 208 to 219
220### Nearest Neighbors
222| cuML | sklearn Equivalent | Multi-GPU |
223|------|-------------------|-----------|
224| `cuml.neighbors.NearestNeighbors` | `sklearn.neighbors.NearestNeighbors` | Yes |
225| `cuml.neighbors.KNeighborsClassifier` | `sklearn.neighbors.KNeighborsClassifier` | Yes |
226| `cuml.neighbors.KNeighborsRegressor` | `sklearn.neighbors.KNeighborsRegressor` | Yes |
227| `cuml.neighbors.KernelDensity` | `sklearn.neighbors.KernelDensity` | No |

Nearest Neighbors

cuMLsklearn EquivalentMulti-GPU
cuml.neighbors.NearestNeighborssklearn.neighbors.NearestNeighborsYes
cuml.neighbors.KNeighborsClassifiersklearn.neighbors.KNeighborsClassifierYes
cuml.neighbors.KNeighborsRegressorsklearn.neighbors.KNeighborsRegressorYes
cuml.neighbors.KernelDensitysklearn.neighbors.KernelDensityNo
Raw lines 220 to 228
229### Time Series
231| cuML | Description |
232|------|-------------|
233| `cuml.ExponentialSmoothing` | Holt-Winters exponential smoothing |
234| `cuml.tsa.ARIMA` | ARIMA/SARIMA models (batched — fits multiple series simultaneously) |
235| `cuml.tsa.auto_arima.AutoARIMA` | Automatic ARIMA order selection |

Time Series

cuMLDescription
cuml.ExponentialSmoothingHolt-Winters exponential smoothing
cuml.tsa.ARIMAARIMA/SARIMA models (batched — fits multiple series simultaneously)
cuml.tsa.auto_arima.AutoARIMAAutomatic ARIMA order selection
Raw lines 229 to 236
237### Metrics (GPU-Accelerated)
239**Regression:** `r2_score`, `mean_squared_error`, `mean_absolute_error`, `mean_squared_log_error`, `median_absolute_error`
241**Classification:** `accuracy_score`, `log_loss`, `roc_auc_score`, `precision_recall_curve`, `confusion_matrix`
243**Clustering:** `adjusted_rand_score`, `silhouette_score`, `silhouette_samples`, `homogeneity_score`, `completeness_score`, `v_measure_score`, `mutual_info_score`
245**Other:** `trustworthiness`, `pairwise_distances`, `pairwise_kernels`

Metrics (GPU-Accelerated)

Regression: r2_score, mean_squared_error, mean_absolute_error, mean_squared_log_error, median_absolute_error

Classification: accuracy_score, log_loss, roc_auc_score, precision_recall_curve, confusion_matrix

Clustering: adjusted_rand_score, silhouette_score, silhouette_samples, homogeneity_score, completeness_score, v_measure_score, mutual_info_score

Other: trustworthiness, pairwise_distances, pairwise_kernels

Raw lines 237 to 246
247### Model Explainability
249| cuML | Description |
250|------|-------------|
251| `cuml.explainer.KernelExplainer` | SHAP Kernel Explainer |
252| `cuml.explainer.PermutationExplainer` | SHAP Permutation Explainer |
253| `cuml.explainer.TreeExplainer` | SHAP Tree Explainer |
255---

Model Explainability

cuMLDescription
cuml.explainer.KernelExplainerSHAP Kernel Explainer
cuml.explainer.PermutationExplainerSHAP Permutation Explainer
cuml.explainer.TreeExplainerSHAP Tree Explainer

Raw lines 247 to 256
257## Input/Output Type Handling

Input/Output Type Handling

Raw lines 257 to 258
259### Supported Input Types
261cuML accepts: NumPy arrays, CuPy arrays, cuDF DataFrames/Series, pandas DataFrames/Series, Numba device arrays, PyTorch tensors (via `__cuda_array_interface__`).
263NumPy and pandas inputs are automatically transferred to GPU. For best performance, pass CuPy arrays or cuDF DataFrames to avoid transfers.

Supported Input Types

cuML accepts: NumPy arrays, CuPy arrays, cuDF DataFrames/Series, pandas DataFrames/Series, Numba device arrays, PyTorch tensors (via __cuda_array_interface__).

NumPy and pandas inputs are automatically transferred to GPU. For best performance, pass CuPy arrays or cuDF DataFrames to avoid transfers.

Raw lines 259 to 264
265### Controlling Output Type
267```python
268import cuml
270# Global setting
271cuml.set_global_output_type('cupy') # Options: 'input', 'cupy', 'numpy', 'cudf', 'pandas'
273# Context manager
274with cuml.using_output_type('cudf'):
275 result = model.predict(X) # Returns cudf Series
277# Per-estimator
278model = cuml.KMeans(output_type='cupy')
279```
281**Performance ranking** (fastest to slowest output type):
2821. `cupy` — no host transfers, most efficient
2832. `cudf` — slight overhead for some shapes
2843. `numpy` / `pandas` — device-to-host transfer cost
286**Best practice:** Use `cupy` or `cudf` for intermediate results. Only convert to `numpy`/`pandas` at the end for visualization or export.
288---

Controlling Output Type

import cuml

# Global setting
cuml.set_global_output_type('cupy')  # Options: 'input', 'cupy', 'numpy', 'cudf', 'pandas'

# Context manager
with cuml.using_output_type('cudf'):
    result = model.predict(X)  # Returns cudf Series

# Per-estimator
model = cuml.KMeans(output_type='cupy')

Performance ranking (fastest to slowest output type):

  1. cupy — no host transfers, most efficient
  2. cudf — slight overhead for some shapes
  3. numpy / pandas — device-to-host transfer cost

Best practice: Use cupy or cudf for intermediate results. Only convert to numpy/pandas at the end for visualization or export.


Raw lines 265 to 289
290## Preprocessing
292cuML provides GPU-accelerated versions of all common sklearn preprocessors.

Preprocessing

cuML provides GPU-accelerated versions of all common sklearn preprocessors.

Raw lines 290 to 293
294### Scalers and Transformers
296```python
297from cuml.preprocessing import StandardScaler, MinMaxScaler, RobustScaler
298from cuml.preprocessing import Normalizer, PowerTransformer, QuantileTransformer
299from cuml.preprocessing import Binarizer, PolynomialFeatures, KBinsDiscretizer
301scaler = StandardScaler()
302X_scaled = scaler.fit_transform(X)
303```

Scalers and Transformers

from cuml.preprocessing import StandardScaler, MinMaxScaler, RobustScaler
from cuml.preprocessing import Normalizer, PowerTransformer, QuantileTransformer
from cuml.preprocessing import Binarizer, PolynomialFeatures, KBinsDiscretizer

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
Raw lines 294 to 304
305### Encoders
307```python
308from cuml.preprocessing import LabelEncoder, OneHotEncoder, LabelBinarizer, TargetEncoder
310le = LabelEncoder()
311y_encoded = le.fit_transform(y)
313ohe = OneHotEncoder(sparse_output=False)
314X_encoded = ohe.fit_transform(X_categorical)
315```

Encoders

from cuml.preprocessing import LabelEncoder, OneHotEncoder, LabelBinarizer, TargetEncoder

le = LabelEncoder()
y_encoded = le.fit_transform(y)

ohe = OneHotEncoder(sparse_output=False)
X_encoded = ohe.fit_transform(X_categorical)
Raw lines 305 to 316
317### Imputers
319```python
320from cuml.preprocessing import SimpleImputer, MissingIndicator
322imputer = SimpleImputer(strategy='mean')
323X_imputed = imputer.fit_transform(X)
324```

Imputers

from cuml.preprocessing import SimpleImputer, MissingIndicator

imputer = SimpleImputer(strategy='mean')
X_imputed = imputer.fit_transform(X)
Raw lines 317 to 325
326### Pipeline and Composition
328```python
329from cuml.compose import ColumnTransformer, make_column_transformer
330from cuml.preprocessing import StandardScaler, OneHotEncoder
332preprocessor = make_column_transformer(
333 (StandardScaler(), ['age', 'income']),
334 (OneHotEncoder(), ['category', 'region']),
336X_processed = preprocessor.fit_transform(df)
337```

Pipeline and Composition

from cuml.compose import ColumnTransformer, make_column_transformer
from cuml.preprocessing import StandardScaler, OneHotEncoder

preprocessor = make_column_transformer(
    (StandardScaler(), ['age', 'income']),
    (OneHotEncoder(), ['category', 'region']),
)
X_processed = preprocessor.fit_transform(df)
Raw lines 326 to 338
339### Preprocessing Functions
341`scale()`, `minmax_scale()`, `maxabs_scale()`, `robust_scale()`, `normalize()`, `binarize()`, `add_dummy_feature()`, `label_binarize()`
343---

Preprocessing Functions

scale(), minmax_scale(), maxabs_scale(), robust_scale(), normalize(), binarize(), add_dummy_feature(), label_binarize()


Raw lines 339 to 344
345## Feature Extraction
347```python
348from cuml.feature_extraction.text import TfidfVectorizer, CountVectorizer, HashingVectorizer
350tfidf = TfidfVectorizer(max_features=10000)
351X_tfidf = tfidf.fit_transform(corpus)
352```
354---

Feature Extraction

from cuml.feature_extraction.text import TfidfVectorizer, CountVectorizer, HashingVectorizer

tfidf = TfidfVectorizer(max_features=10000)
X_tfidf = tfidf.fit_transform(corpus)

Raw lines 345 to 355
356## Model Selection and Tuning

Model Selection and Tuning

Raw lines 356 to 357
358### Train/Test Split
360```python
361from cuml.model_selection import train_test_split
363X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
364```

Train/Test Split

from cuml.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
Raw lines 358 to 365
366### Cross-Validation
368```python
369from cuml.model_selection import KFold
371kf = KFold(n_splits=5, shuffle=True, random_state=42)
372for train_idx, test_idx in kf.split(X):
373 X_train, X_test = X[train_idx], X[test_idx]
374 # ...
375```

Cross-Validation

from cuml.model_selection import KFold

kf = KFold(n_splits=5, shuffle=True, random_state=42)
for train_idx, test_idx in kf.split(X):
    X_train, X_test = X[train_idx], X[test_idx]
    # ...
Raw lines 366 to 376
377### Hyperparameter Tuning
379For an existing sklearn workflow, use `cuml.accel` with sklearn search first and inspect fallback. Bound concurrency per GPU to avoid memory oversubscription. Dask-ML is an optional distributed design, not a guarantee of fewer transfers.
381```python
382import cuml
383cuml.accel.install() # Before sklearn imports, in a fresh process
384from sklearn.model_selection import RandomizedSearchCV
385from sklearn.ensemble import RandomForestClassifier
387param_distributions = {
388 'max_depth': [8, 12, 16, 20],
389 'n_estimators': [100, 200, 500],
390 'max_features': [0.5, 0.75, 1.0],
393search = RandomizedSearchCV(
394 RandomForestClassifier(),
395 param_distributions,
396 n_iter=25,
397 cv=5,
398 random_state=42,
399 n_jobs=1, # One GPU: start with bounded concurrency
401search.fit(X_train, y_train)
402print(f"Best score: {search.best_score_:.4f}")
403print(f"Best params: {search.best_params_}")
404```

Hyperparameter Tuning

For an existing sklearn workflow, use cuml.accel with sklearn search first and inspect fallback. Bound concurrency per GPU to avoid memory oversubscription. Dask-ML is an optional distributed design, not a guarantee of fewer transfers.

import cuml
cuml.accel.install()  # Before sklearn imports, in a fresh process
from sklearn.model_selection import RandomizedSearchCV
from sklearn.ensemble import RandomForestClassifier

param_distributions = {
    'max_depth': [8, 12, 16, 20],
    'n_estimators': [100, 200, 500],
    'max_features': [0.5, 0.75, 1.0],
}

search = RandomizedSearchCV(
    RandomForestClassifier(),
    param_distributions,
    n_iter=25,
    cv=5,
    random_state=42,
    n_jobs=1,  # One GPU: start with bounded concurrency
)
search.fit(X_train, y_train)
print(f"Best score: {search.best_score_:.4f}")
print(f"Best params: {search.best_params_}")
Raw lines 377 to 405
406### Dataset Generators
408```python
409from cuml.datasets import make_blobs, make_classification, make_regression
411X, y = make_blobs(n_samples=100_000, centers=5, n_features=20, random_state=42)
412X, y = make_classification(n_samples=100_000, n_features=50, n_informative=25)
413X, y = make_regression(n_samples=100_000, n_features=50, noise=0.1)
414```
416---

Dataset Generators

from cuml.datasets import make_blobs, make_classification, make_regression

X, y = make_blobs(n_samples=100_000, centers=5, n_features=20, random_state=42)
X, y = make_classification(n_samples=100_000, n_features=50, n_informative=25)
X, y = make_regression(n_samples=100_000, n_features=50, noise=0.1)

Raw lines 406 to 417
418## Forest Inference Library
420`cuml.fil.ForestInference` remains a deprecated compatibility API in 26.08. New forest
421inference work should evaluate [nvForest](https://docs.nvidia.com/nvforest/latest/)
422and its [migration guide](https://docs.nvidia.com/nvforest/latest/fil_migration/).
423Do not infer its removal from a moving cuML `latest` page while using 26.08.
425FIL provides GPU inference for supported tree-based models trained in other frameworks. Its value
426depends on model structure and inference batch size, so compare warm and end-to-end latency with
427the deployment baseline.
429```python
430from cuml.fil import ForestInference
432# Load an XGBoost model file; use load_from_sklearn for a fitted sklearn estimator
433fil_model = ForestInference.load("xgboost_model.ubj", is_classifier=True)
435# Optional: optimize for specific batch size
436fil_model.optimize()
438# Predict on GPU
439predictions = fil_model.predict(X_test)
440probas = fil_model.predict_proba(X_test)
441```
443**Supports:** XGBoost, LightGBM, sklearn Random Forests, any Treelite-compatible model.
445This is especially valuable when you have a model already trained on CPU and want to speed up inference without retraining.
447---

Forest Inference Library

cuml.fil.ForestInference remains a deprecated compatibility API in 26.08. New forest inference work should evaluate nvForest and its migration guide. Do not infer its removal from a moving cuML latest page while using 26.08.

FIL provides GPU inference for supported tree-based models trained in other frameworks. Its value depends on model structure and inference batch size, so compare warm and end-to-end latency with the deployment baseline.

from cuml.fil import ForestInference

# Load an XGBoost model file; use load_from_sklearn for a fitted sklearn estimator
fil_model = ForestInference.load("xgboost_model.ubj", is_classifier=True)

# Optional: optimize for specific batch size
fil_model.optimize()

# Predict on GPU
predictions = fil_model.predict(X_test)
probas = fil_model.predict_proba(X_test)

Supports: XGBoost, LightGBM, sklearn Random Forests, any Treelite-compatible model.

This is especially valuable when you have a model already trained on CPU and want to speed up inference without retraining.


Raw lines 418 to 448
449## Multi-GPU with Dask
451For datasets too large for a single GPU or when you want to use multiple GPUs.
453```python
454from dask.distributed import Client
455from dask_cuda import LocalCUDACluster
457# One Dask worker per GPU
458cluster = LocalCUDACluster(
459 rmm_pool_size="12GB",
460 enable_cudf_spill=True,
462client = Client(cluster)
464# Create distributed data
465from cuml.dask.datasets import make_blobs
466X, y = make_blobs(
467 n_samples=1_000_000,
468 n_features=20,
469 centers=5,
470 n_parts=len(client.scheduler_info()['workers']) * 2, # 2 partitions per worker
473# Use Dask estimator
474from cuml.dask.cluster import KMeans
475kmeans = KMeans(n_clusters=5)
476kmeans.fit(X)
477labels = kmeans.predict(X)
479# Convert to single-GPU model for serialization
480single_model = kmeans.get_combined_model()
482client.close()
483cluster.close()
484```

Multi-GPU with Dask

For datasets too large for a single GPU or when you want to use multiple GPUs.

from dask.distributed import Client
from dask_cuda import LocalCUDACluster

# One Dask worker per GPU
cluster = LocalCUDACluster(
    rmm_pool_size="12GB",
    enable_cudf_spill=True,
)
client = Client(cluster)

# Create distributed data
from cuml.dask.datasets import make_blobs
X, y = make_blobs(
    n_samples=1_000_000,
    n_features=20,
    centers=5,
    n_parts=len(client.scheduler_info()['workers']) * 2,  # 2 partitions per worker
)

# Use Dask estimator
from cuml.dask.cluster import KMeans
kmeans = KMeans(n_clusters=5)
kmeans.fit(X)
labels = kmeans.predict(X)

# Convert to single-GPU model for serialization
single_model = kmeans.get_combined_model()

client.close()
cluster.close()
Raw lines 449 to 485
486### Available Multi-GPU Estimators (`cuml.dask`)
488- **Clustering:** KMeans, DBSCAN
489- **Linear models:** LinearRegression, Ridge, Lasso, ElasticNet
490- **Ensemble:** RandomForestClassifier, RandomForestRegressor
491- **Decomposition:** PCA, TruncatedSVD
492- **Manifold:** UMAP (inference only)
493- **Neighbors:** NearestNeighbors, KNeighborsClassifier, KNeighborsRegressor
494- **Naive Bayes:** MultinomialNB
495- **Preprocessing:** LabelEncoder, LabelBinarizer, OneHotEncoder
497---

Available Multi-GPU Estimators (cuml.dask)

  • Clustering: KMeans, DBSCAN
  • Linear models: LinearRegression, Ridge, Lasso, ElasticNet
  • Ensemble: RandomForestClassifier, RandomForestRegressor
  • Decomposition: PCA, TruncatedSVD
  • Manifold: UMAP (inference only)
  • Neighbors: NearestNeighbors, KNeighborsClassifier, KNeighborsRegressor
  • Naive Bayes: MultinomialNB
  • Preprocessing: LabelEncoder, LabelBinarizer, OneHotEncoder

Raw lines 486 to 498
499## Model Serialization
501```python
502import pickle
504# Save cuML model
505with open("model.pkl", "wb") as f:
506 pickle.dump(model, f, protocol=5)
508# Load cuML model
509with open("model.pkl", "rb") as f:
510 model = pickle.load(f)
511```
513- Models trained under cuml.accel can be pickled and loaded as standard sklearn objects in non-GPU environments.
514- Dask distributed models must be converted first: `single_model = dask_model.get_combined_model()`.
515- joblib also works for serialization.
517---

Model Serialization

import pickle

# Save cuML model
with open("model.pkl", "wb") as f:
    pickle.dump(model, f, protocol=5)

# Load cuML model
with open("model.pkl", "rb") as f:
    model = pickle.load(f)
  • Models trained under cuml.accel can be pickled and loaded as standard sklearn objects in non-GPU environments.
  • Dask distributed models must be converted first: single_model = dask_model.get_combined_model().
  • joblib also works for serialization.

Raw lines 499 to 518
519## Memory Management

Memory Management

Raw lines 519 to 520
521### RMM (RAPIDS Memory Manager)
523```python
524import rmm
526# Pre-allocate a memory pool for faster allocation
527rmm.reinitialize(pool_allocator=True, initial_pool_size=2**32) # 4 GB pool
528```

RMM (RAPIDS Memory Manager)

import rmm

# Pre-allocate a memory pool for faster allocation
rmm.reinitialize(pool_allocator=True, initial_pool_size=2**32)  # 4 GB pool
Raw lines 521 to 529
530### Aligning with cuDF and CuPy
532When using cuML alongside cuDF and CuPy, align all libraries on the same RMM allocator:
534```python
535import rmm
536from rmm.allocators.cupy import rmm_cupy_allocator
537import cupy
538cupy.cuda.set_allocator(rmm_cupy_allocator)
539```

Aligning with cuDF and CuPy

When using cuML alongside cuDF and CuPy, align all libraries on the same RMM allocator:

import rmm
from rmm.allocators.cupy import rmm_cupy_allocator
import cupy
cupy.cuda.set_allocator(rmm_cupy_allocator)
Raw lines 530 to 540
541### cuml.accel Memory
543cuml.accel uses managed memory by default (host RAM augments GPU VRAM). Disable with `--disable-uvm` flag if experiencing slowdowns. Managed memory does NOT work on WSL2 or when RMM is externally configured.

cuml.accel Memory

cuml.accel uses managed memory by default (host RAM augments GPU VRAM). Disable with --disable-uvm flag if experiencing slowdowns. Managed memory does NOT work on WSL2 or when RMM is externally configured.

Raw lines 541 to 544
545### Best Practices
547- float32 halves array storage relative to float64; throughput gains depend on hardware and algorithm.
548- Keep data on GPU throughout the pipeline — avoid NumPy/pandas round-trips.
549- For datasets larger than GPU memory: use Dask multi-GPU or chunk processing.
550- Pre-allocate RMM pools to avoid fragmentation.
552---

Best Practices

  • float32 halves array storage relative to float64; throughput gains depend on hardware and algorithm.
  • Keep data on GPU throughout the pipeline — avoid NumPy/pandas round-trips.
  • For datasets larger than GPU memory: use Dask multi-GPU or chunk processing.
  • Pre-allocate RMM pools to avoid fragmentation.

Raw lines 545 to 553
554## Performance Optimization

Performance Optimization

Raw lines 554 to 555
556### Benchmarking
5581. Verify whether `cuml.accel` used a GPU implementation or fell back to scikit-learn.
5592. Compare the same estimator parameters, train/test split, random seed, and output semantics.
5603. Warm the CUDA context and any lazy compilation before timed repetitions.
5614. Report fit, transform/predict, and end-to-end times separately, including conversion and
562 transfer costs paid by the application.
5635. Record rows, features, sparsity, dtype, estimator parameters, CPU/GPU models, and software
564 versions.
5656. For stochastic or approximate algorithms, compare quality metrics as well as time.

Benchmarking

  1. Verify whether cuml.accel used a GPU implementation or fell back to scikit-learn.
  2. Compare the same estimator parameters, train/test split, random seed, and output semantics.
  3. Warm the CUDA context and any lazy compilation before timed repetitions.
  4. Report fit, transform/predict, and end-to-end times separately, including conversion and transfer costs paid by the application.
  5. Record rows, features, sparsity, dtype, estimator parameters, CPU/GPU models, and software versions.
  6. For stochastic or approximate algorithms, compare quality metrics as well as time.
Raw lines 556 to 566
567### Key Optimization Tips
5691. **Use float32 when the model's accuracy and stability permit it.** Validate metrics after
570changing precision; architecture-specific throughput ratios are not a correctness argument.
5722. **Keep data on GPU.** Pass CuPy arrays or cuDF DataFrames. Every NumPy/pandas conversion triggers a device-host transfer.
5743. **Use enough work to amortize setup and transfer.** Do not rely on a fixed row threshold;
575features, sparsity, estimator, batch size, and reuse all matter.
5774. **Benchmark the actual feature shape.** Width affects compute, memory traffic, and temporary
578storage differently for each estimator.
5805. **First call has JIT overhead.** Benchmark on subsequent calls, not the first.
5826. **Use RMM pools when allocation overhead or fragmentation is visible in profiling.** Pools
583amortize allocator costs but reserve device memory and should be sized deliberately.
5857. **Bound search concurrency per GPU** and measure transfer/fallback behavior. The search scheduler alone does not ensure device residency.
5878. **Evaluate FIL for supported tree-model inference.** Benchmark the target model and production
588batch sizes against the existing serving path.
590---

Key Optimization Tips

  1. Use float32 when the model's accuracy and stability permit it. Validate metrics after

changing precision; architecture-specific throughput ratios are not a correctness argument.

  1. Keep data on GPU. Pass CuPy arrays or cuDF DataFrames. Every NumPy/pandas conversion triggers a device-host transfer.
  1. Use enough work to amortize setup and transfer. Do not rely on a fixed row threshold;

features, sparsity, estimator, batch size, and reuse all matter.

  1. Benchmark the actual feature shape. Width affects compute, memory traffic, and temporary

storage differently for each estimator.

  1. First call has JIT overhead. Benchmark on subsequent calls, not the first.
  1. Use RMM pools when allocation overhead or fragmentation is visible in profiling. Pools

amortize allocator costs but reserve device memory and should be sized deliberately.

  1. Bound search concurrency per GPU and measure transfer/fallback behavior. The search scheduler alone does not ensure device residency.
  1. Evaluate FIL for supported tree-model inference. Benchmark the target model and production

batch sizes against the existing serving path.


Raw lines 567 to 591
592## Interoperability
594- **cuDF:** Accepted by many estimators; assembling dense matrices or changing dtype can copy.
595- **CuPy:** Zero-copy via `__cuda_array_interface__`. Most efficient intermediate format.
596- **NumPy/pandas:** Accepted as input (auto-transferred to GPU). Output type configurable.
597- **PyTorch:** Tensors accepted via array interface.
598- **sklearn:** Similar estimator interfaces. Interconversion is estimator-specific; use cuml.accel for supported transparent acceleration.
599- **XGBoost/LightGBM:** FIL provides GPU inference for externally-trained tree models.
600- **Dask:** Native distributed support via `cuml.dask` module.

Interoperability

  • cuDF: Accepted by many estimators; assembling dense matrices or changing dtype can copy.
  • CuPy: Zero-copy via __cuda_array_interface__. Most efficient intermediate format.
  • NumPy/pandas: Accepted as input (auto-transferred to GPU). Output type configurable.
  • PyTorch: Tensors accepted via array interface.
  • sklearn: Similar estimator interfaces. Interconversion is estimator-specific; use cuml.accel for supported transparent acceleration.
  • XGBoost/LightGBM: FIL provides GPU inference for externally-trained tree models.
  • Dask: Native distributed support via cuml.dask module.
Raw lines 592 to 601
602### End-to-End RAPIDS Pipeline
604```python
605import cudf
606import cuml
607from cuml.preprocessing import StandardScaler
608from cuml.ensemble import RandomForestClassifier
609from cuml.model_selection import train_test_split
611# Load data on GPU
612df = cudf.read_parquet("data.parquet")
613X = df.drop("target", axis=1)
614y = df["target"]
616# Split
617X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
619# Preprocess
620scaler = StandardScaler()
621X_train = scaler.fit_transform(X_train)
622X_test = scaler.transform(X_test)
624# Train
625model = RandomForestClassifier(n_estimators=100, max_depth=16)
626model.fit(X_train, y_train)
628# Evaluate
629score = model.score(X_test, y_test)
630print(f"Accuracy: {score:.4f}")
631```
633The main tabular and estimator stages use GPU data. I/O, setup, scalar scoring/printing, internal conversions, and unsupported operations can still involve the CPU or transfers.
635---

End-to-End RAPIDS Pipeline

import cudf
import cuml
from cuml.preprocessing import StandardScaler
from cuml.ensemble import RandomForestClassifier
from cuml.model_selection import train_test_split

# Load data on GPU
df = cudf.read_parquet("data.parquet")
X = df.drop("target", axis=1)
y = df["target"]

# Split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# Preprocess
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# Train
model = RandomForestClassifier(n_estimators=100, max_depth=16)
model.fit(X_train, y_train)

# Evaluate
score = model.score(X_test, y_test)
print(f"Accuracy: {score:.4f}")

The main tabular and estimator stages use GPU data. I/O, setup, scalar scoring/printing, internal conversions, and unsupported operations can still involve the CPU or transfers.


Raw lines 602 to 636
637## Key Differences from sklearn
6391. **Platform:** Linux and WSL2 only. No native macOS or Windows.
6412. **Sparse data:** Coverage is estimator-specific; do not densify a large sparse matrix blindly or assume all sparse inputs fall back. Check the pinned compatibility page.
6433. **String data:** Must be pre-encoded to numeric. No native string column support in estimators.
6454. **Multi-output:** Not supported for Random Forest.
6475. **Warm starts:** Not supported for most algorithms.
6496. **Unsupported parameters:** May trigger fallback or raise; never silently drop a constraint such as `positive=True` merely to obtain GPU execution.
6517. **Model equivalence:** Different algorithms can change fitted models substantially. Validate scientific conclusions and held-out quality; do not promise equivalent quality.
6538. **Memory:** Limited by GPU VRAM (typically 8-80 GB). Use managed memory or Dask for larger datasets.
6559. **Missing fitted attributes:** Some proxy attributes remain unavailable; inspect the estimator-specific compatibility list before using diagnostics.
657---

Key Differences from sklearn

  1. Platform: Linux and WSL2 only. No native macOS or Windows.
  1. Sparse data: Coverage is estimator-specific; do not densify a large sparse matrix blindly or assume all sparse inputs fall back. Check the pinned compatibility page.
  1. String data: Must be pre-encoded to numeric. No native string column support in estimators.
  1. Multi-output: Not supported for Random Forest.
  1. Warm starts: Not supported for most algorithms.
  1. Unsupported parameters: May trigger fallback or raise; never silently drop a constraint such as positive=True merely to obtain GPU execution.
  1. Model equivalence: Different algorithms can change fitted models substantially. Validate scientific conclusions and held-out quality; do not promise equivalent quality.
  1. Memory: Limited by GPU VRAM (typically 8-80 GB). Use managed memory or Dask for larger datasets.
  1. Missing fitted attributes: Some proxy attributes remain unavailable; inspect the estimator-specific compatibility list before using diagnostics.

Raw lines 637 to 658
659## Common Migration Patterns

Common Migration Patterns

Raw lines 659 to 660
661### Pattern 1: Zero-Effort (cuml.accel)
663```python
664# Add one line at top of notebook:
665%load_ext cuml.accel
667from sklearn.cluster import KMeans # Now GPU-accelerated
668from sklearn.decomposition import PCA # Now GPU-accelerated
669# Everything else stays exactly the same
670```

Pattern 1: Zero-Effort (cuml.accel)

# Add one line at top of notebook:
%load_ext cuml.accel

from sklearn.cluster import KMeans  # Now GPU-accelerated
from sklearn.decomposition import PCA  # Now GPU-accelerated
# Everything else stays exactly the same
Raw lines 661 to 671
672### Pattern 2: Direct Import Swap
674```python
675# Before
676from sklearn.ensemble import RandomForestClassifier
677from sklearn.preprocessing import StandardScaler
678from sklearn.model_selection import train_test_split
680# After
681from cuml.ensemble import RandomForestClassifier
682from cuml.preprocessing import StandardScaler
683from cuml.model_selection import train_test_split
684```

Pattern 2: Direct Import Swap

# Before
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

# After
from cuml.ensemble import RandomForestClassifier
from cuml.preprocessing import StandardScaler
from cuml.model_selection import train_test_split
Raw lines 672 to 685
686### Pattern 3: Full RAPIDS Pipeline (cuDF + cuML)
688```python
689import cudf
690from cuml.preprocessing import StandardScaler, LabelEncoder
691from cuml.ensemble import RandomForestClassifier
692from cuml.model_selection import train_test_split
694# Load and preprocess entirely on GPU
695df = cudf.read_parquet("data.parquet")
696le = LabelEncoder()
697df["category_encoded"] = le.fit_transform(df["category"])
699X = df[["feature1", "feature2", "category_encoded"]].to_cupy()
700y = df["target"].to_cupy()
702X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
704scaler = StandardScaler()
705X_train = scaler.fit_transform(X_train)
706X_test = scaler.transform(X_test)
708model = RandomForestClassifier(n_estimators=200, max_depth=16)
709model.fit(X_train, y_train)
710print(f"Accuracy: {model.score(X_test, y_test):.4f}")
711```

Pattern 3: Full RAPIDS Pipeline (cuDF + cuML)

import cudf
from cuml.preprocessing import StandardScaler, LabelEncoder
from cuml.ensemble import RandomForestClassifier
from cuml.model_selection import train_test_split

# Load and preprocess entirely on GPU
df = cudf.read_parquet("data.parquet")
le = LabelEncoder()
df["category_encoded"] = le.fit_transform(df["category"])

X = df[["feature1", "feature2", "category_encoded"]].to_cupy()
y = df["target"].to_cupy()

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

model = RandomForestClassifier(n_estimators=200, max_depth=16)
model.fit(X_train, y_train)
print(f"Accuracy: {model.score(X_test, y_test):.4f}")
Raw lines 686 to 712
713### Pattern 4: GPU Inference for CPU-Trained Models
715```python
716from cuml.fil import ForestInference
718# Load a supported XGBoost/LightGBM/sklearn model for GPU inference
719fil_model = ForestInference.load("my_xgboost_model.ubj", is_classifier=True)
720predictions = fil_model.predict(X_test)
721```

Pattern 4: GPU Inference for CPU-Trained Models

from cuml.fil import ForestInference

# Load a supported XGBoost/LightGBM/sklearn model for GPU inference
fil_model = ForestInference.load("my_xgboost_model.ubj", is_classifier=True)
predictions = fil_model.predict(X_test)
Raw lines 713 to 721