explainx.ai0k
TrendingAI News TodayPathwaysSkills
Pricing
explainx.ai

Upskill in AI — 16 free pathways, live workshops & bootcamps, and 50+ courses from practitioners. Plus the skills, tools, and MCP servers to practice on.

follow us

follow on google

Add explainx.ai as a preferred source

corporate training

support@explainx.ai

get started

Find your pathTake Free Evaluation

community

Join the community

learn

mind: share how you thinkpathways — start freeworkshopsbootcampscoursescompare Explainxcertificationsmock testsexplainx universitycorporate traininglearn skills & mcp

discover

skillsmcp serversexplainx mcptoolsmdx readeragentsllmsdesignsdictionarypeopleagi trackerfelony benchranks

company

aboutvisionmissionteaminstructorsteach on explainxpartnershipscommunityhackathonscareers

content

daily AI newsstate of AI — live resultsblogreleasespromptsgeneratorsresource libraryfor LLMsexplainx.ai kids

solutions

all solutionsdeveloper upskillingmarketing upskillingproduct manager upskillingleadership upskilling

newsletter · weekly

Get AI news, tools, and insights in your inbox.

supportcontactprivacytermsdata rightshow we create contentsubmission guidelines

© 2026 AISOLO Technologies Pvt Ltd

explainx.ai

On this page

  • TL;DR: what changes for Mac users
  • FP8 arrives on MPS
  • Why decoding got faster
  • Softmax, padding and the 270 GiB bug
  • Linear algebra and new operators
  • Streams and events
  • Preview: what PyTorch 2.16 may bring
  • What this means for what you build
  • Related reading
← Back to blog

explainx / blog

PyTorch 2.15 on Mac: FP8, Faster MoE Decoding and an 8x Softmax on Apple Silicon

PyTorch, Apple Silicon, Local AI, Hugging Face, Open Source AI

Part of Local AI

PyTorch 2.15 adds FP8, native MoE grouped matmul and Metal kernels to MPS. Hugging Face reports 5 to 6.5x faster MoE decoding on an M3 Ultra. The details.

Oct 20, 2026·8 min read·Yash Thakker
add explainx.ai
go deep
PyTorch 2.15 on Mac: FP8, Faster MoE Decoding and an 8x Softmax on Apple Silicon

If you run models on a Mac through PyTorch, the October 20 post "MPS in PyTorch 2.15" on the Hugging Face blog is the most detailed account yet of what changes. Its authors, Irakli Salia and Khushi Agrawal, list FP8 tensors, native mixture-of-experts (MoE) kernels, new Metal implementations of softmax and padding, and a pile of linear algebra fixes. The headline claim is that MoE models decode 5 to 6.5 times faster on Apple Silicon than before. We read the post closely, because the numbers inside it do not all tell the same story.

This is a report on a release described by its maintainers. We have not benchmarked 2.15 ourselves, so every figure below is attributed to the Hugging Face post.

Weekly digest3.6k readers

Catch up on AI

Curated AI updates on agents, skills, and MCP — delivered to your inbox. Unsubscribe anytime.

TL;DR: what changes for Mac users

table · 2 cols
QuestionAnswer from the post
What are the requirements?macOS 15 or later; Python 3.11 or later
Is FP8 supported?Yes: torch.float8_e4m3fn tensors and F.scaled_mm with tensorwise and rowwise scaling
How much faster is MoE decoding?Headline 5 to 6.5x; the 2.14 vs 2.15 table shows about 1.3x with torch.compile
Dense layers?1.23x geometric-mean speedup across 96 BF16 layer shapes on single-row decoding
Softmax?About 8x faster (57 to 7 microseconds for a 128,256-wide FP32 row)
Memory fix?Video VAE decode peak driver memory from about 270 GiB to 8.1 GiB
What is next?PyTorch 2.16 preview: attention on Metal, fewer syncs, smaller install

FP8 arrives on MPS

The release adds torch.float8_e4m3fn on MPS. An FP8 value takes one byte, half of FP16 or BF16, so weights and activations shrink accordingly. F.scaled_mm handles tensorwise and rowwise scaling, and the post's example quantizes a 1 by 1024 input and a 1024 by 1024 weight with per-tensor scales and returns a BF16 output.

For local-model users this is the foundation, not yet the payoff. The post says Metal 4.1 shaders with faster matmuls and native FP8 matmul are being prepared for later. Today, FP8 mostly halves storage and bandwidth; the compute-side win depends on that future work. If you want the wider picture of how people squeeze large models onto Macs, see our posts on local inference with DwarfStar and DFlash 2 on MLX with an M5 Max.

Why decoding got faster

Decoding generates one token at a time, so the work per step is a pile of tiny matrix-vector products. Two changes target that.

Dense layers

F.linear now uses GEMV kernels for single-row inputs, with eligible bias additions fused in. Across 96 BF16 layer shapes the geometric-mean speedup is 1.23x. Gains concentrate in small projections such as MoE gates; large layers and LM heads stay near 1x, which is expected because those are bandwidth-bound already.

Mixture-of-experts

Grouped matmul now has a native MPS implementation. Group offsets are read on the GPU instead of being copied to the CPU, and a dedicated kernel handles the small groups typical of decoding. The post also lists fewer GPU-to-CPU syncs and faster top-k routing. Because MoE models route each token to a few experts, the grouped matmul is the hot path, and avoiding a CPU round trip on every step is a large part of the gain.

Here is the post's 2.14 to 2.15 table on an M3 Ultra with torch.compile:

table · 4 cols
ModelContext2.14 (tokens/s)2.15 (tokens/s)
Qwen3.6-35B-A3B51238.751.7
Qwen3.6-35B-A3B204836.848.7
LFM2.5-8B-A1B51277.1103.2
LFM2.5-8B-A1B204874.998.7

That is roughly a 1.3x improvement. The headline figures are bigger: Qwen3.6-35B-A3B from 9.4 to 61.3 tokens per second, and LFM2.5-8B-A1B from 23.6 to 123.6. The post does not clearly say why the two sets differ; the likely explanation is a different baseline, such as eager mode on an older release versus the compiled path, but the post does not say so. Read "5 to 6.5x" as the best case against a weak starting point, and "1.3x" as the like-for-like kernel gain until the authors clarify. Either way, a 35B-parameter MoE running above 50 tokens per second on a desktop Mac is a useful result. Our write-up of a consumer-GPU run of a 125B MoE and the guide to Qwen 3.6 27B locally give context for what other setups achieve.

Softmax, padding and the 270 GiB bug

Several fixes are less glamorous but matter more for people running image and video models.

  • Softmax and log-softmax run on dedicated Metal kernels. A FP32 softmax over a row of 128,256 values drops from 57 to 7 microseconds, about 8x faster than MPSGraph, and the speedup is 7.1x to 8.0x across vocabularies from 128,256 to 201,088. Softmax over the vocabulary happens on every generated token, so this helps all LLM decoding.
  • Constant padding moved to Metal kernels. In a Wan2.2-TI2V-5B-Diffusers VAE decode, tiled over 28 tiles with 8,764 padding calls, peak total driver memory fell from about 270.1 GiB to 8.1 GiB, per the post's table. Allocator-reserved memory was 8.07 GiB in both cases, so the old path was leaking through driver-level allocations that were not visible in the usual counters.
  • Image corruption fix. On 2.14, the Qwen-Image-2.1 VAE encoder corrupted images on MPS, a problem reported in ComfyUI. With 2.15, an encode-decode round trip matches CPU at 29.95 dB PSNR, up from 10.06 dB.
  • Other kernels: specialized conv1d forward kernels, Metal reflection and replication padding (also fixing backward correctness), a gather kernel for upsampling backward, and the fused dropout kernel for out-of-place dropout.

Linear algebra and new operators

For scientific and vision workloads, the release brings complex64 LU factorization, LU solve and triangular solve to MPS, which unlocks complex determinants. Batches of FP32 matrices up to 4 by 4 are inverted in one Metal kernel, aimed at camera geometry and image transforms. QR uses blocked updates, and there is a fast path for 16, 32 and 64 sized triangular systems used by Gated DeltaNet style layers. SVD handles tiny singular values and extreme magnitudes more robustly, which improves pseudoinverse and least-squares results.

New operators on MPS include torch.frexp, torch.logspace, torch.take, Tensor.put_, torch.heaviside and unsigned-integer comparisons. One stated limitation: logspace does not yet support integer or boolean outputs with more than one element. The math implementation of scaled dot-product attention now handles batch and head broadcasting correctly.

Streams and events

torch.mps.Stream and the torch.mps.stream context manager let Python code choose which stream runs work, and Tensor.record_stream lets the allocator track a tensor used on another stream. This is the same pattern CUDA developers know for overlapping data loading and compute, and it is what pipelines and custom schedulers need. Event timing is also described as more reliable. The post includes a short example that runs work on a separate stream, records the tensor use and synchronizes before reading the result.

Preview: what PyTorch 2.16 may bring

The authors are explicit that some of these are on main or in review and may change.

table · 2 cols
ItemReported effect
Commit command buffers every 16 kernelsLFM2.5-8B-A1B 108.8 to 126.0 tok/s (+16%); Qwen3.6-35B-A3B 52.9 to 62.8 (+19%); Qwen3.8-27B 12.1 to 12.6 (+4%)
Attention fully on MetalM5 Pro grouped-query decode (32 query heads, 8 KV heads, head dim 80, 4K context) 465 to 65 microseconds; 4K by 4K prefill 42 ms to 6 ms
More MPSGraph migrationsMSE loss up to 12x faster on small inputs; std_mean and var_mean up to 4x; bincount on 4M mostly-identical integers from 6.8 s to about half a millisecond
Smaller installDefault Metal 3.1 shaders; libtorch_cpu.dylib from 384 MiB to 287 MiB (about 25%)

The dense Qwen3.8-27B result is the telling one: only 4 percent. Dense models at that size are memory-bandwidth limited, so scheduling tricks help MoE models far more than dense ones.

What this means for what you build

  • Running MoE models locally on Mac is getting practical. If you prototype with Hugging Face transformers on MPS, 2.15 is worth the upgrade, provided you can move to macOS 15.
  • Do not expect miracles on dense models. Gains scale with how much of the step is launch overhead and syncing, not raw bandwidth.
  • Check your OS. The macOS 15 floor drops older machines from MPS support.
  • Benchmark your own model. The headline and the table differ by about 4x, so measure with and without torch.compile on your workload before promising anything to a team.
  • Try the release candidate in a clean environment. The post shows installing from PyTorch's test index with uv pip in a separate environment, and invites bug reports on GitHub for slow, missing or broken MPS behavior. The PyTorch MPS documentation covers the basics of the backend.

For a different corner of the PyTorch ecosystem moving to native stacks, see our take on Amazon TorchNeuron on Trainium and NVIDIA's cuTile Mamba-2 kernels.

Related reading

  • DwarfStar DS4: local inference
  • DFlash 2 on MLX with an M5 Max
  • Strata: 125B MoE on a consumer GPU
  • Qwen 3.6 27B local development guide
  • Amazon TorchNeuron on Trainium: claimed vs verified
  • NVIDIA cuTile Mamba-2 kernels
  • Run MoE models larger than RAM by streaming experts from SSD

Figures are from the Hugging Face post published October 20, 2026 and may change before the final PyTorch 2.15 release.

Spotted something out of date? Let us know.
Yash Thakker

Written by

Yash Thakker

Yash is an AI expert with over 300K learners. Join his workshops →

View Yash Thakker in People in AI →

Related posts

Oct 20, 2026

Hugging Face + TorchTPU: Transformers and Diffusers Now Run on TPUs Natively

Hugging Face has published its TorchTPU integration: Transformers and Diffusers models can target a "tpu" device with ordinary PyTorch code, no torch_xla or JAX rewrite. We walk through the install, the reported numbers and the caveats.

Aug 11, 2026

antirez Ported MiniMax H3 to Apple Silicon — in C and Metal

Salvatore Sanfilippo (antirez) shipped h3.c on August 10, 2026 — MiniMax H3 video generation running natively in C and Metal on Apple Silicon, MIT licensed. MiniMax called it proof that "you can't hire this, you can only open-source and let it happen." The awkward part: H3's own license excludes the EU from local deployment.

Oct 20, 2026

LTX-2.5: Lightricks Ships a 22B Open-Weight Video and Audio Model With Native Multishot

Lightricks has put LTX-2.5 on Hugging Face: a 22B-parameter open-weight model that generates synchronized video and audio, now with native multishot generation. Here is what the model card says, what the license allows, and how to run it locally.