Summary
VulkanWeights.MoeRoutedRawDeviceQuantType can keep a routed MoE expert bank device-resident only when it is Q8_0, Q4_K, Q5_K, Q6_K, or (with coopmat) F16. Everything else falls back to a host F32 dequant, and CanSkipMoeF32HostDequant is model-global all-or-nothing: one unsupported bank forces every bank of every MoE layer through F32.
For DeepSeek-V2-Lite that is ~57 GB of host RAM, which OOMs on a 128 GB box (see #326 for the OOM triage and the exact per-file tensor census).
Two independent gaps
1. Missing quant types. Real, shipping llama.cpp GGUFs use formats we do not cover — and not by accident. DeepSeek-V2-Lite's moe_intermediate_size = 1408 is not a multiple of QK_K = 256, so llama.cpp is forced to fall back to a non-K format for every ffn_down_exps:
| GGUF |
gate_exps |
up_exps |
down_exps |
mradermacher/DeepSeek-V2-Lite-GGUF Q4_K_M |
Q4_K (26) |
Q4_K (26) |
Q5_0 (14), Q8_0 (12) |
bartowski/DeepSeek-Coder-V2-Lite-Instruct-GGUF Q2_K |
Q2_K (26) |
Q2_K (26) |
IQ4_NL (26) |
So Q5_0 and IQ4_NL are not exotic — they are what you get whenever the MoE intermediate size is not a multiple of 256, which is every DeepSeek-V2-Lite / Coder-V2-Lite build. Q2_K covers the whole low-bit MoE tier.
2. All-or-nothing granularity. skipF32MoeDequant is a single bool threaded into TransformerWeights.LoadDeepSeekMoeLayer. In the Q4_K_M file, 64 of 78 routed banks are already device-resident-capable; all 64 are host-dequantised anyway because 14 are Q5_0. Per-bank resolution would cut the footprint by ~80% for that file with no new kernels at all.
The all-or-nothing design is deliberate and documented: with skipF32MoeDequant: true, W1/W2/W3 are left as all-NULL pointer arrays, so a bank that then resolves to the F32 upload path reads a null pointer per expert — silent corruption, not a crash. Making this per-bank therefore requires the F32/raw decision to be represented per bank in MoeLayerWeights, not inferred from a model-wide flag.
Suggested direction
Reuse the indexed MoE MMVQ machinery from #137 (already shipped for Qwen3-MoE banks) to add routed-bank device-resident support for Q5_0, IQ4_NL and Q2_K, and make the skip decision per bank rather than per model. Gap 2 is the cheaper and higher-leverage half and can land first.
Acceptance criteria
Summary
VulkanWeights.MoeRoutedRawDeviceQuantTypecan keep a routed MoE expert bank device-resident only when it isQ8_0,Q4_K,Q5_K,Q6_K, or (with coopmat)F16. Everything else falls back to a host F32 dequant, andCanSkipMoeF32HostDequantis model-global all-or-nothing: one unsupported bank forces every bank of every MoE layer through F32.For DeepSeek-V2-Lite that is ~57 GB of host RAM, which OOMs on a 128 GB box (see #326 for the OOM triage and the exact per-file tensor census).
Two independent gaps
1. Missing quant types. Real, shipping llama.cpp GGUFs use formats we do not cover — and not by accident. DeepSeek-V2-Lite's
moe_intermediate_size = 1408is not a multiple ofQK_K = 256, so llama.cpp is forced to fall back to a non-K format for everyffn_down_exps:mradermacher/DeepSeek-V2-Lite-GGUFQ4_K_Mbartowski/DeepSeek-Coder-V2-Lite-Instruct-GGUFQ2_KSo
Q5_0andIQ4_NLare not exotic — they are what you get whenever the MoE intermediate size is not a multiple of 256, which is every DeepSeek-V2-Lite / Coder-V2-Lite build.Q2_Kcovers the whole low-bit MoE tier.2. All-or-nothing granularity.
skipF32MoeDequantis a single bool threaded intoTransformerWeights.LoadDeepSeekMoeLayer. In the Q4_K_M file, 64 of 78 routed banks are already device-resident-capable; all 64 are host-dequantised anyway because 14 areQ5_0. Per-bank resolution would cut the footprint by ~80% for that file with no new kernels at all.The all-or-nothing design is deliberate and documented: with
skipF32MoeDequant: true,W1/W2/W3are left as all-NULL pointer arrays, so a bank that then resolves to the F32 upload path reads a null pointer per expert — silent corruption, not a crash. Making this per-bank therefore requires the F32/raw decision to be represented per bank inMoeLayerWeights, not inferred from a model-wide flag.Suggested direction
Reuse the indexed MoE MMVQ machinery from #137 (already shipped for Qwen3-MoE banks) to add routed-bank device-resident support for
Q5_0,IQ4_NLandQ2_K, and make the skip decision per bank rather than per model. Gap 2 is the cheaper and higher-leverage half and can land first.Acceptance criteria
MoeLayerWeightscarrying the per-bank decision so a null-pointer F32 read is structurally impossible.Q5_0,IQ4_NL,Q2_Krouted banks stay device-resident.deepseek-v2-lite-q4_k_manddeepseek-coder-v2-lite-q2_kload on Vulkan on a 128 GB box and passRealGgufVulkanParityTests.