Skip to main content

flash-kmeans-mlx

IO-aware batched K-Means for Apple Silicon, ported from Flash-KMeans (Triton/CUDA) to pure MLX.

500K points, 128 dimensions, K=1000 clustered in 0.76s on M3 Ultra -- 160x faster than sklearn. Uses custom Metal kernels for argmax, fused addmm assignment, and multi-iteration compiled execution.

Full Fashion-MNIST (70K samples, 784 dimensions, K=10) clustered in 0.12s on M3 Ultra, 6x faster than sklearn (0.74s). Left: K-Means cluster assignments. Right: ground truth labels. Visualization via mlx-vis UMAP.

Fashion-MNIST K-Means vs Ground Truth

Installation

uv pip install flash-kmeans-mlx

From source:

git clone https://github.com/hanxiao/flash-kmeans-mlx.git
cd flash-kmeans-mlx
uv pip install .

Usage

Functional API

import mlx.core as mx
from flash_kmeans_mlx import batch_kmeans_Euclid

x = mx.random.normal((32, 75600, 128))
cluster_ids, centers, n_iters = batch_kmeans_Euclid(
    x, n_clusters=1000, tol=1e-4, verbose=True
)

Input shape is (B, N, D) where B is batch size, N is number of points, D is dimensionality. All batches are clustered independently in a single vectorized pass.

Three distance metrics are available: batch_kmeans_Euclid, batch_kmeans_Cosine, and batch_kmeans_Dot.

Class API

from flash_kmeans_mlx import FlashKMeans

model = FlashKMeans(d=128, k=1000, niter=25, tol=1e-6)
model.fit(x)
labels = model.predict(x_new)

# or in one step
labels = model.fit_predict(x)

The FlashKMeans class accepts both (N, D) and (B, N, D) inputs. Set metric="cosine" or metric="dot" to switch distance functions.

Benchmark

All timings on M3 Ultra, float32, single batch. MLX uses mx.compile; sklearn uses Lloyd's algorithm on CPU (n_init=1).

N D K Iters MLX sklearn Speedup
5K 64 50 10 2ms 34ms 17x
50K 128 256 20 7ms 1.28s 183x
100K 128 1000 20 32ms 9.8s 306x
500K 128 1000 10 77ms 39.8s 517x

Run the benchmark yourself:

uv pip install 'flash-kmeans-mlx[benchmark]'
python -m flash_kmeans_mlx.benchmark --n 100000 --d 128 --k 1000 --max-iters 20

vs H200 GPU

Comparison against the original Flash-KMeans and other PyTorch implementations on NVIDIA H200 (FP16). All methods run D=128, 100 iterations. MLX on M3 Ultra matches or beats naive PyTorch methods on H200, with the gap to the Triton kernel explained by the 37x raw compute difference (27 TFLOPS vs 990 TFLOPS).

H200 vs M3 Ultra benchmark

Correctness

Verified against sklearn with identical initial centroids over 20 iterations. Cluster assignment agreement is 92-99.8% depending on configuration, with inertia difference below 0.01%. The remaining discrepancy comes from float32 vs sklearn's float64 accumulation - boundary points near equidistant cluster borders get assigned differently due to rounding.

Distance metrics

Euclidean (squared L2), Cosine (dot product on L2-normalized vectors), and Dot-product (raw inner product).

Credits

This is an independent MLX port of Flash-KMeans and is not affiliated with the original authors.

Papers:

License

Apache 2.0

Metadata

Release files for flash-kmeans-mlx 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for flash-kmeans-mlx 0.1.1
File Size Uploaded Provenance
flash_kmeans_mlx-0.1.1.tar.gz 17.9 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for flash-kmeans-mlx 0.1.1
File Interpreter ABI Platform
flash_kmeans_mlx-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 35.8 kB

Release files / flash_kmeans_mlx-0.1.1.tar.gz

Download URL flash_kmeans_mlx-0.1.1.tar.gz
Size 17.9 kB
Tags Source
SHA-256 checksum
How to use checksums
2cff8b4a71f9aae4dcf139fc8512f4c962659a8a99bba145333c7569218b850c
BLAKE2b-256 checksum
How to use checksums
6d2fa00b65b09517f487681e67e78ba20806bf5112ce391529a32deff0900a52
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.8

Release files / flash_kmeans_mlx-0.1.1-py3-none-any.whl

Download URL flash_kmeans_mlx-0.1.1-py3-none-any.whl
Size 17.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c7cd63e3599d1bf2918c6366d2b2ff217e16c1b95111d2ce84fb7af7fac415ba
BLAKE2b-256 checksum
How to use checksums
178fd8357bb350ce5e41d46bc850724eb30917e1d958e8b6604851f5e298bee9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.8

Security for flash-kmeans-mlx 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page