fix(loader): gate CUTLASS grouped NVFP4 MoE on architecture, not model_type string#260
fix(loader): gate CUTLASS grouped NVFP4 MoE on architecture, not model_type string#260rsafier wants to merge 1 commit into
Conversation
Runtime regression — PASS (validated on the actual binary, both models)Built AgentWorld (
Holo-3.1-35B-A3B-NVFP4 (
No kernels moved; |
…ot model_type
check_kernel_batched_eligible() blocked batched-prefill attention for MLA models
via `config.model_type == "mistral"` — a hardcoded proxy the author flagged as
conservative ("mistral is the only MLA model in Atlas today"). Key it on the
actual MLA capability instead: `config.kv_lora_rank > 0` (== AttentionType::Mla).
- signature: `model_type: &str` -> `is_mla: bool`; wrapper passes
`self.config.kv_lora_rank > 0` (the exact derivation of
capabilities().attention_type == Mla; read directly to avoid rebuilding the
full ModelCapabilities struct on this per-prefill-batch hot path).
- tests updated to pass the bool.
Behavior-preserving on every shipped model: kv_lora_rank>0 == {mistral,
deepseek_v4}; all other model_types have kv_lora_rank=0 -> is_mla=false ->
unchanged. deepseek_v4 is the only newly-matched model, but it is ALREADY
rejected one check later by `head_dim > 256` (head_dim=512), so its outcome
(not batched-eligible) is identical. Also future-proofs any MLA checkpoint
shipped with head_dim<=256. Unit tests (batch_kernel_tests) pass.
Stacked on Avarok-Cybersecurity#260 (fix/generic-nvfp4-moe-gate). NOTE: an exhaustive adversarial
pass over the OTHER model_type gates found this is the ONLY additional safe
architecture-generic conversion — notably the MTP allowlist (preflight.rs) must
NOT be converted to has_mtp (broader than intent: would re-enable the
MiniMax/DeepSeek per-module-MTP path the guard rejects). See PR description.
…ot model_type (#261) check_kernel_batched_eligible() blocked batched-prefill attention for MLA models via `config.model_type == "mistral"` — a hardcoded proxy the author flagged as conservative ("mistral is the only MLA model in Atlas today"). Key it on the actual MLA capability instead: `config.kv_lora_rank > 0` (== AttentionType::Mla). - signature: `model_type: &str` -> `is_mla: bool`; wrapper passes `self.config.kv_lora_rank > 0` (the exact derivation of capabilities().attention_type == Mla; read directly to avoid rebuilding the full ModelCapabilities struct on this per-prefill-batch hot path). - tests updated to pass the bool. Behavior-preserving on every shipped model: kv_lora_rank>0 == {mistral, deepseek_v4}; all other model_types have kv_lora_rank=0 -> is_mla=false -> unchanged. deepseek_v4 is the only newly-matched model, but it is ALREADY rejected one check later by `head_dim > 256` (head_dim=512), so its outcome (not batched-eligible) is identical. Also future-proofs any MLA checkpoint shipped with head_dim<=256. Unit tests (batch_kernel_tests) pass. Stacked on #260 (fix/generic-nvfp4-moe-gate). NOTE: an exhaustive adversarial pass over the OTHER model_type gates found this is the ONLY additional safe architecture-generic conversion — notably the MTP allowlist (preflight.rs) must NOT be converted to has_mtp (broader than intent: would re-enable the MiniMax/DeepSeek per-module-MTP path the guard rejects). See PR description.
[BETA] Automated PR review — SeedSource AI pipelineAdvisory only, not a merge gate. AI-generated (internal risk-triage, Atlas serve gate, GLM-5.2 review), attributed per Atlas convention. Triage
Serve gate
GLM-5.2 code reviewCorrectness: Sound. Gating on Risk: Moderate. The broadened Quality: Comment updates are accurate and well-scoped. Pipeline: build+serve on GB10, GLM-5.2 via NVIDIA NIM, internal risk-triage classifier. External diff treated as untrusted input. Public repo. |
650e5ce to
cb79d49
Compare
…ot model_type
check_kernel_batched_eligible() blocked batched-prefill attention for MLA models
via `config.model_type == "mistral"` — a hardcoded proxy the author flagged as
conservative ("mistral is the only MLA model in Atlas today"). Key it on the
actual MLA capability instead: `config.kv_lora_rank > 0` (== AttentionType::Mla).
- signature: `model_type: &str` -> `is_mla: bool`; wrapper passes
`self.config.kv_lora_rank > 0` (the exact derivation of
capabilities().attention_type == Mla; read directly to avoid rebuilding the
full ModelCapabilities struct on this per-prefill-batch hot path).
- tests updated to pass the bool.
Behavior-preserving on every shipped model: kv_lora_rank>0 == {mistral,
deepseek_v4}; all other model_types have kv_lora_rank=0 -> is_mla=false ->
unchanged. deepseek_v4 is the only newly-matched model, but it is ALREADY
rejected one check later by `head_dim > 256` (head_dim=512), so its outcome
(not batched-eligible) is identical. Also future-proofs any MLA checkpoint
shipped with head_dim<=256. Unit tests (batch_kernel_tests) pass.
Stacked on #260 (fix/generic-nvfp4-moe-gate). NOTE: an exhaustive adversarial
pass over the OTHER model_type gates found this is the ONLY additional safe
architecture-generic conversion — notably the MTP allowlist (preflight.rs) must
NOT be converted to has_mtp (broader than intent: would re-enable the
MiniMax/DeepSeek per-module-MTP path the guard rejects). See PR description.
cb79d49 to
fdc6bba
Compare
…ot model_type
check_kernel_batched_eligible() blocked batched-prefill attention for MLA models
via `config.model_type == "mistral"` — a hardcoded proxy the author flagged as
conservative ("mistral is the only MLA model in Atlas today"). Key it on the
actual MLA capability instead: `config.kv_lora_rank > 0` (== AttentionType::Mla).
- signature: `model_type: &str` -> `is_mla: bool`; wrapper passes
`self.config.kv_lora_rank > 0` (the exact derivation of
capabilities().attention_type == Mla; read directly to avoid rebuilding the
full ModelCapabilities struct on this per-prefill-batch hot path).
- tests updated to pass the bool.
Behavior-preserving on every shipped model: kv_lora_rank>0 == {mistral,
deepseek_v4}; all other model_types have kv_lora_rank=0 -> is_mla=false ->
unchanged. deepseek_v4 is the only newly-matched model, but it is ALREADY
rejected one check later by `head_dim > 256` (head_dim=512), so its outcome
(not batched-eligible) is identical. Also future-proofs any MLA checkpoint
shipped with head_dim<=256. Unit tests (batch_kernel_tests) pass.
Stacked on #260 (fix/generic-nvfp4-moe-gate). NOTE: an exhaustive adversarial
pass over the OTHER model_type gates found this is the ONLY additional safe
architecture-generic conversion — notably the MTP allowlist (preflight.rs) must
NOT be converted to has_mtp (broader than intent: would re-enable the
MiniMax/DeepSeek per-module-MTP path the guard rejects). See PR description.
…l_type string The fast CUTLASS grouped NVFP4 MoE path (opt-in via ATLAS_HOLO_LOW_MEMORY_MOE=1) was gated on `config.model_type == "holo3_1_moe"`, silently dropping every other NVFP4-MoE checkpoint to the slow `moe_w4a16` path. But holo3_1_moe / qwen3_5_moe / qwen3_6_moe are the SAME architecture at the weight level (factory:: loader_for_config maps all three to Qwen35WeightLoader); "holo3_1_moe" is a label fabricated at config/dispatch.rs purely for kernel-target directory lookup. The grouped path operates on the loaded NVFP4 experts regardless of source quant format (the inline comment already said so). Repro: Qwen-AgentWorld-35B-A3B-NVFP4 (model_type qwen3_5_moe, compressed-tensors NVFP4) fell back to moe_w4a16 even with LOW_MEMORY_MOE=1. Fix — gate on the architecture (MoE + NVFP4), not the label: - holo_nvfp4_moe -> nvfp4_moe = `config.num_experts > 0 && quant_format == Nvfp4` - is_holo_modelopt_mixed_precision -> is_modelopt_mixed_precision: drop the `model_type == "holo3_1_moe"` conjunct, keep the quant-config test. No kernels move; the config/dispatch.rs model_type rewrites (kernel-dir resolution) are untouched. holo3_1_moe still qualifies (num_experts=256, Nvfp4) so Holo-3.1-35B is unchanged; the mixed-precision path still fires for Holo and now also for any architecturally-identical sibling shipping the same quant.
fdc6bba to
6a48210
Compare
…ot model_type
check_kernel_batched_eligible() blocked batched-prefill attention for MLA models
via `config.model_type == "mistral"` — a hardcoded proxy the author flagged as
conservative ("mistral is the only MLA model in Atlas today"). Key it on the
actual MLA capability instead: `config.kv_lora_rank > 0` (== AttentionType::Mla).
- signature: `model_type: &str` -> `is_mla: bool`; wrapper passes
`self.config.kv_lora_rank > 0` (the exact derivation of
capabilities().attention_type == Mla; read directly to avoid rebuilding the
full ModelCapabilities struct on this per-prefill-batch hot path).
- tests updated to pass the bool.
Behavior-preserving on every shipped model: kv_lora_rank>0 == {mistral,
deepseek_v4}; all other model_types have kv_lora_rank=0 -> is_mla=false ->
unchanged. deepseek_v4 is the only newly-matched model, but it is ALREADY
rejected one check later by `head_dim > 256` (head_dim=512), so its outcome
(not batched-eligible) is identical. Also future-proofs any MLA checkpoint
shipped with head_dim<=256. Unit tests (batch_kernel_tests) pass.
Stacked on #260 (fix/generic-nvfp4-moe-gate). NOTE: an exhaustive adversarial
pass over the OTHER model_type gates found this is the ONLY additional safe
architecture-generic conversion — notably the MTP allowlist (preflight.rs) must
NOT be converted to has_mtp (broader than intent: would re-enable the
MiniMax/DeepSeek per-module-MTP path the guard rejects). See PR description.
Draft until the runtime regression check lands (building now — validating Holo-3.1-35B and AgentWorld both engage CUTLASS grouped + stay coherent on the actual binary).
Problem
The fast CUTLASS grouped NVFP4 MoE path (opt-in via
ATLAS_HOLO_LOW_MEMORY_MOE=1) was gated onconfig.model_type == "holo3_1_moe", so any other NVFP4-MoE checkpoint silently fell back to the slowmoe_w4a16path even with the flag set. Concrete repro:sakamakismile/Qwen-AgentWorld-35B-A3B-NVFP4(model_typeqwen3_5_moe, compressed-tensors NVFP4) — noCUTLASS grouped SFBsignal, ranmoe_w4a16.But
holo3_1_moe/qwen3_5_moe/qwen3_6_moeare the same architecture at the weight level —factory::loader_for_configmaps all three toQwen35WeightLoader, andholo3_1_moeis a label fabricated atconfig/dispatch.rs:120-128(rewritesqwen3_5_moe→holo3_1_moewhenimage_token_id==248056) purely so kernel-target directory lookup can disambiguate 3.5 vs 3.6 (they collide on hidden=2048). Downstream code then mistook that label for an architecture discriminator.Fix (2 gates, one file —
qwen35/load_layers.rs)holo_nvfp4_moe→nvfp4_moe = config.num_experts > 0 && quant_format == Nvfp4(architecture, not label).is_holo_modelopt_mixed_precision→is_modelopt_mixed_precision: drop themodel_type == "holo3_1_moe"conjunct; keep the quant-config test (any Qwen3.5/3.6-family MoE shipping modelopt MIXED_PRECISION is now recognized).Scope / safety
config/dispatch.rsmodel_type rewrites (needed for kernel-directory resolution) are deliberately untouched — this only changes which MoE dispatch fires, not kernel layout.holo3_1_moestill qualifies (num_experts=256, Nvfp4), and the mixed-precision path still fires for Holo (modelopt MIXED_PRECISION). It now also fires for architecturally-identical siblings shipping the same quant format — no existing checkpoint changes behavior (we ship no non-Holo modelopt-MIXED MoE).