Skip to content

finegrained-kernels: add rowwise FP8 across GEMMs and MoE - #1240

Open
IlyasMoutawwakil wants to merge 26 commits into
mainfrom
finegrained-rowwise-fp8
Open

IlyasMoutawwakil wants to merge 26 commits into
mainfrom
finegrained-rowwise-fp8

Conversation

@IlyasMoutawwakil

@IlyasMoutawwakil IlyasMoutawwakil commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Support per-output-row FP8 weight scales and per-token activation scales across dense, batched, grouped, and MoE GEMMs, reusing existing loading, scaling, scheduling, and epilogue helpers. Fused MoE requires matching gate/up and down recipes. Dgrad stays in its separate stream.

Dense rowwise dispatch uses public torch.nn.functional.scaled_mm in its measured M65–8192 range, preserving Triton decode and accumulation precision. Eager, fullgraph compilation, and CUDA graph capture were checked to reach the public route with identical outputs.

bench_moe.py adds Llama 4 Scout routed experts and its actual GQA QKV shape (N7168/K5120), comparing Torch, FBGEMM/MSLK, and vLLM. All 48 timing cells passed. The Torch reference uses the public API; MoE uses per-expert dense GEMMs with fixed routing bounds prepared outside timing. Router/shared expert are excluded and sigmoid input weights are prepared equally for every arm. FlashInfer has no compatible rowwise arm in the inspected backends; vLLM MoE uses its heuristic config.

B200 decode graph / eager prefill: routed MoE 36.0 / 1188.8 µs; dense QKV 7.8 / 254.9 µs. Routed MoE is 1.92× / 1.88× faster than Torch and 1.60× / 2.02× faster than vLLM in those modes. A separate matched-input, normally tuned A/B measured about 6% lower full-MoE latency from grouping neighboring M tiles for weight reuse. These are synthetic operator measurements, not model throughput. Torch2.13+cu130, Triton3.7.1, vLLM0.29, MSLK1.3.

The refreshed plot includes the configured activation cap: Torch, MSLK and finegrained receive 1200; vLLM exposes no equivalent argument, but the benchmark values stay below the cap. All 48 timing cells completed. QKV graphed prefill ties Torch and trails vLLM; compiled MoE decode also trails native alternatives. Maximum cross-implementation relative maximum-element difference is 3.04% for MoE; each compiled arm passes its eager-versus-compiled check.

Llama 4 Scout MoE and dense comparison on B200

Tests extend existing Problem/MoEProblem and configuration-sweep tables, including compiled prequantized inputs and default output dtype. Ruff and diff checks passed. Companion #1237 improves generic tuning; no rowwise-specific tuning override is added.

Related issue

Requested by a maintainer for huggingface/transformers#49658.

Checklist

  • Linked to a discussed issue
  • Tested locally
  • New/changed functionality has test coverage
  • Mostly or completely generated with an LLM

IlyasMoutawwakil and others added 13 commits October 14, 2026 23:07
…token activations)

E4M3 weights with one fp32 scale per output row and dynamic per-token activation scales (the
Llama 4 FP8 recipe) run on the tensor-wide kernels: the weight scale is constant along K, so it
folds after the K-loop like a per-tensor one, read per row (a per-tensor scale is stride 0).

- formats: is_rowwise / per_token_activations / row_scale_stride; weight_block_size routes (E, N, 1)
  to the tensor-wide ops
- kernels: apply_row_scale in the 2D / batched / grouped tensor-wide kernels (gate|up rows carry
  their scales interleaved)
- 2D tensor-wide kernel: host-TMA A/B arms, SWAP_AB decode rows, PDL, derived per-token rows padded
  to the largest M tile, native_mma_m_pruner, 200 trials
- matmul_2d: cuBLAS RowWise route for 65 <= M < 4096; the scaled_mm routes are plain functions
  inside the opaque ops
- MoE: per-token formats hand the down a bf16 intermediate
- quant: fp8_act_quant_tensor_wide gains amax_upper_bound and row_multiple
- backward: row-wise 2D dgrad on the natural-tile kernel (scale groups wider than the K tile);
  grouped tensor-wide / row-wise dgrad registered
- fixes: the grouped prefill expansion carries per-token scales with their rows; WS + descriptor
  compile failures fenced on the grouped tensor-wide kernel
- tests: fp8_rowwise registry row and scenarios, scaled_mm parity, MoE cells, amax bound,
  row-wise dgrad, forced-config sweep cells

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Preserve compact prequantized inputs with safe TMA padding, mask tail activation scales, and normalize leading activation dimensions. Separate gated batched tuning keys and keep the measured decode tile pruning specific to Blackwell. Add public-loader eager and fullgraph regressions and document the batched training boundary.
@github-actions

Copy link
Copy Markdown

This PR changes source code for the following kernel(s): finegrained-kernels.

If you have the kernel-bot build permissions, then trigger /kernel-bot build finegrained-kernels yourself. Otherwise, a maintainer will review the PR and will take an appropriate action. Thanks for your patience.

@github-actions github-actions Bot added the chore Version bumps, releases, misc maintenance label Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore Version bumps, releases, misc maintenance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant