Prhub

#36603 fix(kimi-k3): preserve dense ModelSlim MLA weights

原始 PR 作者 McZyWu 合并时间 2026-08-28 17:15 文件变更 3 提交数 4 评论 2 代码增减 +22 / -3

执行摘要

修复 Kimi-K3 ModelSlim MLA 权重被误删问题

Kimi-K3 ModelSlim W4A8 多节点精度任务在加载 351 个 checkpoint 分片后失败,报错 ValueError: Kimi-K3 MLA K projection must remain GGUF Q4_0。#35314 为 Kimi-K3 ExpertPack 路径添加了 split-GGUF K/V 支持,但错误地通过 supports_kimi_k3_quantized_latent_projections 来触发该路径。ModelSlim 虽然声明支持该能力(用于 latent-MoE 线性层),但其 MLA checkpoint 中 kv_b_proj.weight 仍是普通密集 FLOAT 张量,导致模型构建时误删 kv_b_proj,注册了未加载的 GGUF 占位符,最终在加载后 Q4_0/Q2_K 校验失败。

值得精读。该 PR 展示了一个典型的能力膨胀导致的行为错误及修复方式:通过拆分粒度更细的能力标志,避免语义混淆。适合对量化加载、模型构建配置有深入兴趣的工程师阅读。

讨论亮点

Issue 评论区主要包含作者的详细验证说明,无 Review 分歧。作者在评论中报告了四节点 64 NPU 硬件验证结果:351/351 分片加载成功,无原始 MLA 后加载错误,服务器正常启动,GSM8K 200 题准确率 97.0%。

实现拆解

  1. 新增能力标志:在 ExpertPackConfig(python/sglang/srt/layers/quantization/expert_pack.py)中新增类属性 supports_kimi_k3_split_gguf_kv_b = True,明确标识使用 split-GGUF MLA K/V 表示。
  2. 引入判断函数:在 kimi_k3.py 中新增 _uses_split_gguf_kv_b(quant_config),通过 getattr(quant_config, 'supports_kimi_k3_split_gguf_kv_b', False) 判断,避免直接依赖旧的通用能力。
  3. 调整构建逻辑:在 KimiK3MLAAttention.__init__ 中,将原来的 split_gguf_kv_b = getattr(quant_config, 'supports_kimi_k3_quantized_latent_projections', False) 改为调用 _uses_split_gguf_kv_b,使得只有在显式声明 split-GGUF 能力时才删除 kv_b_proj,ModelSlim 保持密集路径。
  4. 新增回归测试:在 test_kimi_k3_gguf.py 新增 test_split_kv_capability_is_expert_pack_specific,断言 ModelSlim 不启用 split-GGUF,而 SimpleNamespace 显式启用时才返回 True,防止回归。
文件 模块 状态 重要度
python/sglang/srt/models/kimi_k3.py 模型层 modified 6.72
python/sglang/srt/layers/quantization/expert_pack.py 量化模块 modified 4.75
test/registered/expert_pack/test_kimi_k3_gguf.py 测试 modified 5.1

关键符号

_uses_split_gguf_kv_b KimiK3MLAAttention.__init__

关键源码片段

python/sglang/srt/models/kimi_k3.py data-contract

核心修改文件,添加 `_uses_split_gguf_kv_b` 并调整 `KimiK3MLAAttention` 的构建逻辑,直接修复 ModelSlim 密集 MLA 权重被误删的问题。

# python/sglang/srt/models/kimi_k3.py ( 关键片段 )
from sglang.srt.layers.quantization.base_quantization import QuantizationConfigdef _uses_split_gguf_kv_b(quant_config: Optional[QuantizationConfig]) -> bool:
    """判断 K3 是否使用 split-GGUF 存储 MLA K/V,只有显式启用该能力的配置才返回 True。"""
    return bool(getattr(quant_config, "supports_kimi_k3_split_gguf_kv_b", False))class KimiK3MLAAttention(DeepseekV2AttentionMLA):
    """带输出门的 MLA 注意力层,仅用于 K3。"""
​
    def __init__(self, config, layer_idx, quant_config=None, ...):
        # ModelSlim 仅量化 latent 投影,而 MLA KV 投影仍是单个密集张量;
        # 只有 GGUF expert pack 才会拆分 K/V,因此必须用专用标志判断。
        split_gguf_kv_b = _uses_split_gguf_kv_b(quant_config)
        self.all_reduce_fusion = all_reduce_fusion
        self.use_output_gate = getattr(config, "mla_use_output_gate", False)
        self._disable_npu_fused_split_qk_norm = True # 数值不等价,禁用融合路径
        super().__init__(...)
        if split_gguf_kv_b:
            del self.fused_qkv_a_proj_with_mqa
            del self.kv_b_proj # 仅 split-GGUF 场景才需要删除
            ...
        # 否则保留 kv_b_proj,确保 ModelSlim 密集权重正常加载
python/sglang/srt/layers/quantization/expert_pack.py core-logic

新增 `supports_kimi_k3_split_gguf_kv_b` 能力标志,确保 ExpertPack 路径继续使用 split-GGUF,与 ModelSlim 区分开。

# python/sglang/srt/layers/quantization/expert_pack.py ( 关键片段 )
class ExpertPackConfig(GGUFConfig):
    """Expert Pack 专用量化配置。"""
​
    is_fp4_experts = True
    # ModelSlim 也声明支持 latent 投影量化,但 MLA 仍为密集权重,
    # 因此不能复用此标志来判断 split-GGUF。
    supports_kimi_k3_quantized_latent_projections = True
    # 新增独立标志,仅 ExpertPack 使用 split-GGUF 存储 MLA K/V。
    supports_kimi_k3_split_gguf_kv_b = True
​
    def __init__(self, store: ExpertPackStore) -> None:
        super().__init__()
        self.store = store
test/registered/expert_pack/test_kimi_k3_gguf.py test-coverage

新增回归测试,验证 ModelSlim 和 split-GGUF 的能力区分,防止回归。

# test/registered/expert_pack/test_kimi_k3_gguf.py ( 关键片段 )
from sglang.srt.layers.quantization.modelslim.modelslim import ModelSlimConfig
from sglang.srt.models.kimi_k3 import _uses_split_gguf_kv_bclass TestKimiK3GGUFMapping(unittest.TestCase):
    def test_split_kv_capability_is_expert_pack_specific(self) -> None:
        # ModelSlim 声明 latent 投影量化,但仍使用密集 MLA,不应触发 split-GGUF。
        self.assertTrue(ModelSlimConfig.supports_kimi_k3_quantized_latent_projections)
        self.assertFalse(_uses_split_gguf_kv_b(ModelSlimConfig))
        # 显式声明 split-GGUF 能力时应返回 True。
        self.assertTrue(
            _uses_split_gguf_kv_b(
                SimpleNamespace(supports_kimi_k3_split_gguf_kv_b=True)
            )
        )

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

  1. 回归风险:修改了 KimiK3MLAAttention 的构建逻辑,若其他量化路径(如 GGUF/ExpertPack)依赖旧行为,可能受影响。但本 PR 通过新增独立标志并保持 ExpertPackConfig 显式启用,降低了风险。
  2. 测试覆盖:新增测试仅验证能力标志判断,未覆盖实际 ModelSlim 权重加载 E2E 流程(依赖硬件)。
  3. 多节点验证:四节点 NPU 验证结果报告成功,但未在 CUDA 环境跑 GGUF/ExpertPack E2E(作者说明硬件限制)。

用户侧:修复了 Kimi-K3 ModelSlim 用户无法加载 checkpoint 的问题,使其能在多节点 NPU 上正常推理。系统侧:新增配置能力标志,不影响其他模型或量化路径。团队侧:提供了清晰的回归测试,防止未来重蹈覆辙。影响范围限于 Kimi-K3 MLA 量化加载路径。

核心加载路径变更 缺少正式 E2E 测试 NPU 特定修复

关联 Issue

#35314 Support deepseek v4 and kimi k3 on ssd

完整报告

参与讨论