Repository navigation
Benchmarking a native-MLX GPT (minGPT's gpt-mini) against PyTorch+MPS, partition by partition #1446
bahaehmimdi
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
I've been benchmarking MLX vs. PyTorch+MPS on a couple of real model
ports (an M1 Pro), and wanted to share the GPT side since it validates
something
transformer_lmalready does, with numbers behind it, plus apartition-level breakdown of why.
Setup
karpathy/minGPT's
gpt-miniconfig (6 layer, 6 head, 192 embd, 2.71Mparams), vendored unmodified, vs. a from-scratch
mx.nn/mx.coreportmatching the same architecture. Same compile pattern
transformer_lmalready uses:
mx.compile(step, inputs=state, outputs=state)(neededbecause
optimizer.updatemutates state in place — plainmx.compile(step)errors with "Attempting to eval an array without aprimitive").
Partition-by-partition (forward/backward/optimizer split apart, real shapes, batch 64 / block 128)
MLX wins every partition tested here — including forward+backward
uncompiled (119ms vs. MPS's 128ms).
End to end
Stable across 5 separate runs (88.4–88.9ms).
The contrasting case, for balance
I ran the identical methodology against RIFE (video frame
interpolation, small-batch Conv2d + resize + backward-warp) on the same
machine, and got the opposite result: PyTorch MPS won every single
partition there, not just the aggregate. So "MLX wins" isn't a
backend-wide property — it's architecture-dependent, and worth actually
measuring per model rather than assuming either direction. One concrete
thing that did fall out of the RIFE side:
nn.Upsample's bilinearmode measured 2-4x slower than a matmul-based resize when upsampling —
filed as #4435 with a repro, since that looks like a real, fixable gap
rather than an architecture mismatch.
Happy to share the benchmark scripts if useful (they're a thin vendor of
minGPT + a from-scratch
mlx_gpt.py, nothing that would make sense asa PR on top of
transformer_lmsince the pattern's already there) —mostly wanted to put real numbers behind it.
All reactions