Prhub

#46168 [Bugfix] Preserve FP8 indexer WK pairs across incremental load_weights

原始 PR 作者 lcheng321 合并时间 2026-07-07 00:16 文件变更 1 提交数 8 评论 4 代码增减 +4 / -1

执行摘要

修复 FP8 indexer WK 对在增量加载时丢失的问题

Issue #46078 报告:GLM-5.x FP8 检查点在流式加载时,由于 _pending_wk_fp8 是 load_weights() 的局部变量,indexer.wk.weight 和 indexer.wk.weight_scale_inv 如果在不同调用中到达,则无法配对,导致 wk_weights_proj 参数包含 NaN/未初始化值,产生损坏的稀疏 MLA 输出。

建议合并。这是一个小而精准的 bugfix,修复了影响生成质量的严重问题,且改动量极小、风险可控。值得关注的是利用实例属性跨调用保存状态的通用模式,类似场景可借鉴。

讨论亮点

本 PR 没有 review 评论。审核者 Isotr0py 和 NickLucche 均直接批准,无讨论。Issue #46078 中 @bvolpato-dd 提出了将 pending 字典提升为实例属性的修复方案,本 PR 实现了该方案。

实现拆解

  1. 在 vllm/model_executor/models/deepseek_v2.py 的 load_weights() 方法中,将原本的局部变量 _pending_wk_fp8: dict = {} 替换为模型实例属性的惰性初始化:使用 getattr(self, '_pending_indexer_wk_fp8', None) 检查,若不存在则创建空字典并赋给 self._pending_indexer_wk_fp8。
  2. 后续逻辑无需修改,因为 _try_load_fp8_indexer_wk() 在成功配对后会自动从字典中移除键,因此字典在完整加载后自清空。
  3. 单次调用加载路径不受影响,行为无变化。
  4. 无新增测试文件,但作者已在 GLM-5.2-FP8 上验证:最终加载后 pending 字典为空,融合的 WK 参数完全有限,生成正常。
文件 模块 状态 重要度
vllm/model_executor/models/deepseek_v2.py 模型执行器 modified 5.91

关键源码片段

vllm/model_executor/models/deepseek_v2.py core-logic

核心变更文件:将 load_weights() 中的局部变量 _pending_wk_fp8 提升为模型实例属性 _pending_indexer_wk_fp8,以跨调用保存 FP8 WK 配对状态。

# vllm/model_executor/models/deepseek_v2.py 中 load_weights() 方法的关键片段
​
def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
    # ... 其他初始化代码 ...
​
    # Fused indexer wk + weights_proj (shard 0 = wk, shard 1 = weights_proj)
    # 将 pending 字典提升为实例属性,以支持跨 load_weights() 调用的增量加载
    _pending_wk_fp8 = getattr(self, "_pending_indexer_wk_fp8", None)
    if _pending_wk_fp8 is None:
        self._pending_indexer_wk_fp8 = _pending_wk_fp8 = {}
​
    # 注意:_try_load_fp8_indexer_wk() 会在成功配对后自动从字典中移除键
    # 因此字典在完整加载后自清空,不影响后续使用
​
    indexer_fused_mapping = [
        ("wk_weights_proj", "wk", 0),
        ("wk_weights_proj", "weights_proj", 1),
    ]
    stacked_params_mapping.extend(indexer_fused_mapping)
    # ... 其余加载逻辑 ...

评论区精华

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

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

风险与影响

风险极低:仅修改了 4 行,将变量作用域从函数局部提升为实例属性,改动明确且局部化。不影响已有的单次加载路径,只影响流式加载场景。未引入新依赖或 API 变化。

影响范围限于 DeepSeek V2 模型族(含 GLM-5.x),且仅在使用流式加载器(如 S3 或 RunAI)导致权重分片分开传递时才会触发。修复后生成结果从损坏变为正常,对用户影响显著。

缺少测试覆盖

关联 Issue

#46078 Preserve FP8 indexer WK pairs across incremental load_weights calls

完整报告

参与讨论