Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions docs/design_docs/flashinfer_moe_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,19 @@ config = MoEConfig(
),
quant=QuantConfig(QuantDtype.FP4, QuantGranularity.BlockScale),
experts=ExpertConfig(intermediate_size=2048, local_num_experts=32),
backends=[TrtllmFp4Config(extra_backend_params...), CutlassConfig(extra_backend_params...)],
backends=[TrtllmFp4Config(extra_backend_params...), CutlassNvfp4Config()],
)
# --- Find possible backends ---
backends = MoELayer.find_backends(**config)
# this contains {"trtllm_fp4":TrtllmFp4Config(), "cutlass_fp4":CutlassConfig()}
# or {"trtllm_fp4":"unsupported reason...", "cutlass_fp4":CutlassConfig()}
# this contains {"trtllm_fp4":TrtllmFp4Config(), "cutlass_nvfp4":CutlassNvfp4Config()}
# or {"trtllm_fp4":"unsupported reason...", "cutlass_nvfp4":CutlassNvfp4Config()}
# more modification to the backends' parameters could be done here
backends=["trtllm_fp4":TrtllmFp4Config(extra_backend_params...),"cutlass_fp4":CutlassConfig(extra_backend_params...)]
backends=["trtllm_fp4":TrtllmFp4Config(extra_backend_params...),"cutlass_nvfp4":CutlassNvfp4Config()]
# --- Prepare Inputs Data ---
weight_pack = MoEWeightPack()
# the data is possibly obtained through helper functions then added here
weight_pack.prepare_for("trtllm_fp4", trtllm_weights) weight_pack.prepare_for("cutlass_fp4", cutlass_weights)
weight_pack.prepare_for("trtllm_fp4", trtllm_weights)
weight_pack.prepare_for("cutlass_nvfp4", CutlassNvfp4Config.prepare_weights(...))
act_pack = MoEActivationPack(
hidden_states_q=cute_dsl_data["x"],
hidden_states_scale=x_sf,
Expand Down Expand Up @@ -120,9 +121,8 @@ Individual backend configs provided in an ordered list. The autotuner or heurist
# Single backend
backends = [TrtllmFp4Config()]
# Multiple candidates β€” autotuner or heuristic picks best
backends = [TrtllmFp4Config(), TrtllmFp8BlockConfig(), CutlassConfig()]
backends = [TrtllmFp4Config(), CutlassNvfp4Config()]
# | is associative, returns BackendOptions
# CutlassConfig is always the universal fallback
```

Each backend config declares its own preconditions:
Expand All @@ -131,11 +131,11 @@ Each backend config declares its own preconditions:
class TrtllmFp4Config:
@classmethod
def supported(cls, arch: int) -> bool:
return arch >= 90 # Hopper+
class CutlassConfig:
return arch in (100, 103, 107)
class CutlassNvfp4Config:
@classmethod
def supported(cls, arch: int) -> bool:
return True # universal fallback
return arch in (100, 103, 107, 110, 120, 121)
```

### 3.3 MoEConfig β€” \*\*unpack protocol
Expand All @@ -147,7 +147,7 @@ config = MoEConfig(
routing=RoutingConfig(num_experts=256, top_k=8, method=RoutingMethodType.DeepSeekV3),
quant=QuantConfig(QuantDtype.FP4, QuantGranularity.BlockScale),
experts=ExpertConfig(intermediate_size=2048, local_num_experts=32),
backends=[TrtllmFp4Config(), CutlassConfig()],
backends=[TrtllmFp4Config(), CutlassNvfp4Config()],
)
# Unpack into any call accepting these kwargs
output = moe_layer(tensors, **config)
Expand Down Expand Up @@ -258,7 +258,7 @@ repro.benchmark_all()
# FinalizeConfig 0.11ms
# Total 3.13ms
# Isolate backend to narrow regression
repro.isolate_backend(CutlassConfig())
repro.isolate_backend(CutlassNvfp4Config())
repro.isolate_backend(TrtllmFp4Config())
```

Expand Down Expand Up @@ -297,7 +297,7 @@ flashinfer/
__init__.py # BACKEND_REGISTRY, DEFAULT_PRIORITY
trtllm_fp4.py # TrtllmFp4Config + adapter
trtllm_fp8.py # Fp8Block + Fp8PerTensor + adapters
cutlass.py # CutlassConfig + adapter
cutlass.py # CutlassBf16 / W4A16 / Nvfp4 / Fp8 / Mxfp8 / W4A8 / Humming + adapters
repro.py # MoERepro
tensors.py # MoETensors, Gemm1Tensors, Gemm2Tensors
```
Expand Down Expand Up @@ -689,7 +689,8 @@ out = layer(act, weights) # subsequent calls: cached winner dispatch
Key mechanisms (and where they live):

- **Two packs, two lifetimes.** `MoEWeightPack` holds long-lived, backend-native weight materializations keyed by `backend_key` (`prepare_for` / `get_view`); `MoEActivationPack` carries per-call pre-routed activations. This is the concrete answer to reviewers' "backends need different weight preprocessing" concern (C29–C32): each backend stores its own view, none is hidden from the caller.
- **First-class prep.** `TrtllmFp4Config.prepare_weights(...)` / `CuteDslConfig.prepare_weights(...)` (backed by `flashinfer/fused_moe/prepare.py`) turn canonical bf16 weights into the native views (C6/C7).
- **First-class prep.** `TrtllmFp4Config.prepare_weights(...)` / `CuteDslConfig.prepare_weights(...)` / `CutlassNvfp4Config.prepare_weights(...)` (and the other quant-specific `Cutlass*Config.prepare_weights` helpers, backed by `flashinfer/fused_moe/prepare.py`) turn canonical bf16 weights into the native views (C6/C7). CUTLASS NVFP4 uses swizzled `fp4_quantize` scales, not the TRTLLM shuffle / BlockMajorK path. CUTLASS FP8 / MXFP8 / W4A8 / Humming likewise keep unshuffled or mixed-input layouts distinct from TRTLLM. Each quant mode uses its matching `Cutlass*Config` / `Cutlass*Runner`; there is no quant-neutral CUTLASS fallback.
- **Breaking change β€” `CutlassConfig` removed.** The deprecated, unregistered `CutlassConfig` placeholder is gone. It was never a runnable `MoELayer` backend (`supported()` always returned false; it was not in `_BACKEND_RUNNERS`). Import, annotate, serialize, or feature-detect a quant-specific type instead (`CutlassBf16Config`, `CutlassNvfp4Config`, `CutlassFp8PerTensorConfig`, `CutlassFp8BlockConfig`, `CutlassMxfp8Config`, `CutlassMxfp8Mxfp4Config`, `CutlassW4A16Config`, `CutlassW4A8Config`, `CutlassHummingConfig`). Historical **Anchor:** / CR1 quotes earlier in this document still mention `CutlassConfig` as review history, not current API.
- **Two-stage cross-backend autotune** (`MoELayer._select_winner`, runners' delegation): for each candidate, the `AutoTuner.choose_one` picks the best *within-backend tactic* (each backend tuned in its own native input schema), then `bench_gpu_time` compares the candidates at their winning tactics and the fastest backend is dispatched. A single `choose_one` over both runners is not possible because their input schemas differ β€” hence the explicit two stages.
- **Winner caching is per token-bucket** (`map_to_hybrid_bucket`): reusing one `MoELayer` across token counts re-selects per bucket; `winner_backend` reports the most-recent choice and `reset_winner()` clears the cache.
- **Fail-fast scope** (`MoELayer._validate_mvp_scope`): non-NVFP4 quant or non-Swiglu activation raises `NotImplementedError` at construction.
Expand Down
34 changes: 30 additions & 4 deletions flashinfer/fused_moe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,15 @@
B12xW4A16Config,
BackendOptions,
CuteDslConfig,
CutlassConfig,
CutlassBf16Config,
CutlassFp8BlockConfig,
CutlassFp8PerTensorConfig,
CutlassHummingConfig,
CutlassMxfp8Config,
CutlassMxfp8Mxfp4Config,
CutlassNvfp4Config,
CutlassW4A16Config,
CutlassW4A8Config,
ExecutionConfig,
ExpertConfig,
MoEActivationPack,
Expand All @@ -49,7 +55,14 @@
B12xNvfp4Runner,
B12xW4A16Runner,
CutlassBf16Runner,
CutlassFp8BlockRunner,
CutlassFp8PerTensorRunner,
CutlassHummingRunner,
CutlassMxfp8Mxfp4Runner,
CutlassMxfp8Runner,
CutlassNvfp4Runner,
CutlassW4A16Runner,
CutlassW4A8Runner,
CuteDslNvfp4Runner,
TrtllmBf16RoutedRunner,
TrtllmFp4RoutedRunner,
Expand Down Expand Up @@ -151,15 +164,28 @@
"ActivationConfig",
"B12xNvfp4Config",
"B12xNvfp4Runner",
"CutlassBf16Runner",
"CutlassW4A16Runner",
"B12xW4A16Config",
"B12xW4A16Runner",
"BackendOptions",
"CuteDslConfig",
"CutlassConfig",
"CutlassBf16Config",
"CutlassBf16Runner",
"CutlassFp8BlockConfig",
"CutlassFp8BlockRunner",
"CutlassFp8PerTensorConfig",
"CutlassFp8PerTensorRunner",
"CutlassHummingConfig",
"CutlassHummingRunner",
"CutlassMxfp8Config",
"CutlassMxfp8Mxfp4Config",
"CutlassMxfp8Mxfp4Runner",
"CutlassMxfp8Runner",
"CutlassNvfp4Config",
"CutlassNvfp4Runner",
"CutlassW4A16Config",
"CutlassW4A16Runner",
"CutlassW4A8Config",
"CutlassW4A8Runner",
"ExecutionConfig",
"ExpertConfig",
"CuteDslNvfp4Runner",
Expand Down
Loading
Loading