PyTorch 2.14 ships NVGEMM kernels — NVGEMM epilogue fusion — What does it mean?
The news. On September 2, 2026, PyTorch released version 2.14, landing 2,995 commits from 487 contributors. Inductor gains CuTeDSL-generated NVGEMM kernels, which are autotuned alongside Triton and ATen and support fused epilogues and scaled or NVFP4 GEMMs. The release also ships a complete nccl2 collective backend with nonblocking communicators and eager split, in-place process-group repair — the release notes call it the point at which "Fault tolerance becomes a first-class c10d concept" — CUDA graph capture for
torch.while_loop, Rubinsm_107support, and Python 3.15 in eager mode. Read the release →
Picture the bakery. The loaf is one matrix multiply — say a 4096 x 4096 projection inside an attention block — and the shop has three ovens that can bake it. The stock oven is ATen: it came with the shop, NVIDIA tuned it, and it is genuinely excellent at the loaf sizes they had in mind. The second oven is Triton, which you assemble yourself from a short recipe describing tiles and staging; torch.compile writes that recipe on your behalf. NVGEMM is the third oven, and it is built to the shape of this particular loaf — CuTeDSL emits a CUTLASS kernel specialized to your dimensions, your dtype, and the work that comes after the multiply.
The interesting part is not the third oven. It is that the shop no longer guesses which oven is best — it bakes the loaf in all three and keeps the fastest. This is autotuning, and it matters because the winner flips on details you cannot reliably reason about from the source: the exact matrix dimensions (M, N and K), whether those dimensions are multiples of the tensor-core tile, how much of the weight matrix stays resident in cache. A backend fixed once at library-build time is only fastest for the shapes its author happened to measure. Inductor compiles the candidates, times them on your real shapes, and caches the answer — the same measure-rather-than-guess discipline you meet in torch.compile.
Now the glaze. A matmul almost never ends at the multiply: there is a bias to add, a GELU or SiLU to apply, sometimes a scale factor to fold back in for a quantized model. That work is arithmetically trivial and ruinously expensive to move. In the bakery it means carrying every finished loaf across the room to a glazing bench and carrying it back. On a GPU it means the output tile leaves the streaming multiprocessor that produced it, is written out to HBM, and is read straight back in by a second kernel that performs almost no arithmetic. A fused epilogue glazes the loaf inside the oven — the bias and the activation run while the result is still sitting in registers, before it is ever written out. That is operator fusion, and what NVGEMM changes is that CUTLASS epilogues become available on a generated matmul rather than only on a hand-written kernel.
Unfused (3 kernels)
6 HBM accesses
Fused (1 kernel)
+ bias
+ ReLU
2 HBM accesses
3× fewer HBM accesses — same computation
Put numbers on the round trip. Take one 4096 x 4096 output tile in bf16 (16-bit brain float, 2 bytes per number — see Precision Formats) — illustrative, since the release publishes no benchmark figures of its own. The tile holds 16,777,216 elements at 2 bytes each, so it is 33.6 MB. Unfused, that tile is written out by the matmul, read back in by the bias-and-activation kernel, and written out once more: three touches, 100.7 MB of HBM traffic. Fused, it is written exactly once: 33.6 MB. On a GPU with 3 TB/s of memory bandwidth (illustrative) that is 33.6 µs versus 11.2 µs — and the arithmetic bought by the two extra touches is one add and one activation per element. The multiply was never the problem; the round trip was. That ratio is why fusion shows up everywhere once you start looking for it, and why the roofline model puts an element-wise epilogue firmly on the memory-bound side of the ridge.
| Kernel source | Where it comes from | Epilogue fusion | The catch |
|---|---|---|---|
| ATen | Prebuilt vendor library (cuBLAS / cuBLASLt), fixed when PyTorch was built | Fixed menu — only the epilogues the vendor exposes | No specialization to your shapes |
| Triton | Generated by Inductor from a Python block-level recipe | Yes, for pointwise chains Inductor can prove are safe to fuse | Block-level abstraction, so the lowest-level tensor-core scheduling is the compiler's call |
| NVGEMM (new in 2.14) | CuTeDSL generates a CUTLASS kernel specialized to the shape | Yes — CUTLASS epilogues, including scaled and NVFP4 GEMMs | One more candidate to generate and benchmark, so compile time grows |
Goes deeper in: GPU & CUDA → Operator Fusion & FlashAttention → Operator Fusion
Related explainers
- INT8 finally beats FP8 on consumer GPUs — Fused INT8 GEMM kernel — the same epilogue trick pushed into quantization, with dequantization and bias folded into the GEMM instead of run as a separate pass.
- Atrex-Bench tests LLM-written kernels on production traces — what goes wrong when candidate kernels are timed on the wrong shapes, which is exactly the failure autotuning is trying to avoid.
- vLLM 0.25.1 stops a fused kernel from corrupting NVFP4 models — the other face of fusion: a fused kernel that was silently wrong for one dtype combination.