Conversation
zianglih
requested review from
Alisehen,
AniZpZ,
BBuf,
Edwardf0t1,
FlamingoPg,
HaiShaw,
OrangeRedeng,
b8zhong,
ch-wan and
mmangkad
as code owners
September 6, 2026 11:23
mmangkad
reviewed
Sep 6, 2026
Comment on lines
+93
to
+97
| if envs.SGLANG_MOE_NVFP4_DISPATCH.get(): | ||
| raise ValueError( | ||
| "CuTe DSL NVFP4 W4A16 requires BF16 MoE dispatch; " | ||
| "unset SGLANG_MOE_NVFP4_DISPATCH." | ||
| ) |
Collaborator
There was a problem hiding this comment.
I think this can go, since use_dispatch_fp4 already excludes W4A16
Comment on lines
+88
to
+92
| if view.moe_a2a_backend not in ("none", "flashinfer"): | ||
| raise ValueError( | ||
| "CuTe DSL NVFP4 W4A16 requires " | ||
| "moe_a2a_backend='none' or 'flashinfer'." | ||
| ) |
Collaborator
There was a problem hiding this comment.
Maybe move this into handle_a2a_moe
| import os | ||
| from typing import Any | ||
|
|
||
| import torch |
Collaborator
There was a problem hiding this comment.
This should be function-local
| if view.moe_a2a_backend == "deepep" and ( | ||
| if envs.SGLANG_FLASHINFER_CUTEDSL_NVFP4_W4A16.get(): | ||
| if not get_platform().is_sm100: | ||
| raise ValueError("CuTe DSL NVFP4 W4A16 requires SM100/SM103 GPUs.") |
Collaborator
There was a problem hiding this comment.
Nit
Suggested change
| raise ValueError("CuTe DSL NVFP4 W4A16 requires SM100/SM103 GPUs.") | |
| raise ValueError("CuTe DSL NVFP4 W4A16 requires SM10X GPUs.") |
Comment on lines
+2258
to
+2262
| for name in ( | ||
| "SGLANG_FLASHINFER_NVFP4_PER_TOKEN_ACTIVATION", | ||
| "SGLANG_MOE_NVFP4_DISPATCH", | ||
| ): | ||
| os.environ.pop(name, None) |
Collaborator
There was a problem hiding this comment.
Could these be envs.X.override(...) instead
| with self.assertRaisesRegex(ValueError, "use --dtype bfloat16"): | ||
| handle_moe_kernel_config(args) | ||
|
|
||
| def test_online_w4a4_still_accepts_per_token_activation(self): |
Collaborator
There was a problem hiding this comment.
Maybe add moe_a2a_backend="deepep" here too, that's the branch the elif refactor actually touches
zianglih
marked this pull request as draft
September 6, 2026 15:54
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
@HumansAnd
CuTe DSL W4A16 demonstrates strong performance in FlashInfer #4985: 1.28–2.61x faster than pure TRTLLM BF16 across its three measured configurations. The complete tables below motivate validating this SGLang configuration:
The implementation from #35120 already loads NVFP4 expert weights online and keeps activations in BF16. This small follow-up validates hardware/dtype/A2A constraints early, skips an unused activation-scale check, and documents the W4A16 opt-in. The FlashInfer results are local-MoE microbenchmarks, not an end-to-end SGLang speedup claim.
Modifications
handle_moe_kernel_config; check supported W4A16 A2A backends (none/flashinfer) inhandle_a2a_moe, after backend overrides.SGLANG_MOE_NVFP4_DISPATCH. Preserve the existing FlashInfer A2A-specific guard. Skip the unused raw activation-scale equality/scalarization for W4A16, since online scale buffers can contain uninitialized values before neutralization.=0env overrides. Remove broad new behavioral test scaffolding in a separate cleanup commit; validation helpers remain outside the PR.Accuracy Tests
a938aec0f7f3439e056eb80a14bf595e617c4c70, base938dc5621d30f6983d97b092015304a35591a7cf. The GPU results below predate review follow-upd8c8b0b6db7e892687eac0dde630ae9620125513and test-cleanup head8a7cd7b56a3ad112e4affd453169d72deb77d508. The review changes only relocate argument gates and skip unused W4A16 raw-scale validation; the full-model GPU tests were not rerun after that follow-up.lmsysorg/sglang:nightly-dev-cu13-20260906-09daea94; amd64 digestsha256:a0d0f199e15d12e14e18c3a331316cfda82df9d15e49873f960e7d05caf346cb.2.13.0+cu130, CUDA 13.0, FlashInfer Python/Cubin/JIT cache0.6.18/0.6.18/0.6.18+cu130, CuTe DSL 4.6.2, Transformers 5.12.1, NVIDIA driver 590.48.01. No package replacement or dependency fallback.Review follow-up validation
Final source:
8a7cd7b56a3ad112e4affd453169d72deb77d508. The behavioral-test removal is a separate commit from the review fixes. A temporary CPU devbox uses the same explicit SGLang image listed above; no GPU is requested for this follow-up.The registered suite passed 296 tests and 79 subtests, with one existing CPU-platform skip (
mxfp4quantization is not registered). Local helpers also passed 16 tests and 2 subtests, including the reviewer-requested DeepEP checks, W4A16 dispatch contracts, and a NaN-scale case through real online scale preparation. Those helpers are preserved outside the final PR tree; the separate cleanup commit removes 190 lines of broad behavioral tests.Complete raw registered-test output
Complete raw local validation output
The argument/dispatch helpers are recoverable from review commit
d8c8b0b6db7e892687eac0dde630ae9620125513; the local NaN case calls the actual online MoE scale preparation with NaN input scales andMOE_NVFP4_DISPATCH=True, stopping at dispatcher configuration before GPU layout conversion. It verifies unit activation scales, weight-only alphas, andinput_global_scale=None.Pre-commit, Python compilation, and diff checks passed on the final head. No new full-model or performance benchmark was run for this review follow-up.
Initial GPU validation
Full-model validation uses
nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-FP8(snapshot744b1880a37996c5d56bf454ae164dfd74d77c4e), online expert-weight conversion, TP4/DP4/EP4, DP attention/LM head, EAGLE with 3 steps/top-k 1/4 draft tokens, decode CUDA graphs, and prefill graphs disabled. Each arm runs the existing 200 GSM8K examples at temperature 1.0/top-p 0.95/max-tokens 16000; thresholds remain score > 0.90 and speculative acceptance > 2.5.The existing nightly case uses FlashInfer A2A. A temporary subclass removes only
--moe-a2a-backend flashinferto validate the same W4A16 configuration with no A2A. Neither case sets the per-token activation or NVFP4-dispatch env to zero; the W4A16 opt-in is sufficient.Reproduction commands in the image/check-out above:
Raw results, in order FlashInfer A2A, then no A2A:
Both runs passed startup, online conversion, CUDA graph capture, 200 requests, and the unchanged accuracy/acceptance thresholds. Scores are stochastic quality checks, not a numerical-parity claim.
Runtime proof of the selected wrapper and BF16 activation contract
A temporary
sitecustomize.pyprobe outside the PR checks the actual FlashInfer constructor and each wrapper's first successful run. All four workers in each arm selectedw4a16and passed BF16 inputs with no activation scales. Local validation also checks the online-method payload and rejects either activation quantizer being called, including when the per-token env is enabled. This helper is retained outside the PR after removing the broad behavioral test scaffolding.To reproduce the instrumentation, put the following file at
/tmp/w4a16-probe/sitecustomize.pyand prepend/tmp/w4a16-probetoPYTHONPATHbefore running the commands above:git diff --checkpassed.Speed Tests and Profiling
Motivation: FlashInfer W4A16 performance
FlashInfer PR #4985 reports strong CuTe DSL W4A16 performance: 1.28–2.61x over pure TRTLLM BF16 across all 39 configuration/token-count comparisons. Against TRTLLM NVFP4, the maximum W4A16 speedups are 1.56x, 1.66x, and 1.73x for inference per-tensor, inference per-token, and deterministic RL, respectively; the tables also preserve the slower cases. This motivates validating that
--quantization nvfp4_online,--moe-runner-backend flashinfer_cutedsl, andSGLANG_FLASHINFER_CUTEDSL_NVFP4_W4A16=1reliably select the existing W4A16 path with BF16 activations.1ac2233d43df747af455ed4a8406d7439d686d9f(0.6.18). They predate later benchmark refactoring; the source PR contains all nine complete raw result tables and setup/reproduction commands.nvcr.io/nvidia/pytorch:26.05-py3, digestnvcr.io/nvidia/pytorch@sha256:222d8b18e671be5c3ef91cb41727a2572a0b23f59ded6c39f373a96946f6f2ba; CUDA 13.2 (nvcc V13.2.78), PyTorch2.12.0a0+5aff3928d8.nv26.05, Python 3.12.3, CuTe DSL[cu13]==4.7.0.Latencies are medians of three fresh-process runs, calculated from unrounded captures and displayed in milliseconds to three decimal places. Each W4A16 speedup is the named TRTLLM baseline's median latency divided by the CuTe DSL W4A16 median latency at that token count. These are ratios of medians; values above 1 mean W4A16 is faster; values below 1 mean W4A16 is slower. Both NVFP4 and pure BF16 comparisons are explicit.
Inference per-tensor — median of three runs
Inference per-token — median of three runs
Deterministic RL — median of three runs
Scope of this evidence: these are historical FlashInfer single-GPU local-expert microbenchmarks that motivate validating the SGLang configuration; this PR does not claim a measured SGLang end-to-end speedup. EP dispatch/combine, collectives, network, and the rest of the model are excluded. Native TRTLLM logits routing stores selected weights in BF16 while CuTe route weights are FP32, so these results do not establish numerical parity. Separate inference sweeps remeasure the unaffected W4A16/BF16 paths; differences between those sweeps cannot be attributed solely to activation scaling. Coverage is B300/SM103 and the stated shapes.
No SGLang performance benchmark was run for this follow-up. Throughput printed by the accuracy harness is incidental; those runs used temporary runtime assertions.
Checklist
Review and Merge Process
/tag-and-rerun-ci,/tag-run-ci-label,/rerun-failed-ciCI States
Latest PR Test (Base): ❌ Run #34044380251
Latest PR Test (Extra): ❌ Run #34044380578
Latest PR Test (AMD ROCm 7.2): ❌ Run #34044380101