Prhub

#51432 [Bugfix][multi_modal] Fix pos_ids being unitialized for minicpmv2.6 in hf runner

原始 PR 作者 music-dino 合并时间 2026-08-08 12:09 文件变更 1 提交数 1 评论 4 代码增减 +18 / -0

执行摘要

修复 MiniCPM-V2.6 HF 测试中 pos_embed 未初始化导致的 flaky

PR body 指出 #48413 在 Multi-Modal Models(Extended Generation 3)TG 引入了两类失败,一类是 NameError: name 'List' is not defined,另一类是 AttributeError: 'MiniCPMV' object has no attribute 'all_tied_weights_keys';后者修复后测试仍 flaky,表现为 HF 输出全 NaN 或 hf/vllm 输出不一致。通过临时 instrumentation 定位到 NaN 出现在模型加载阶段而非前向过程:vLLM 的 pos_embed 是正常 sin/cos 表,HF 的却是全 0。根因是 transformers 的 _move_missing_keys_from_meta_to_device 把 non-persistent 缓冲区替换为 torch.empty_like,而 _initialize_missing_keys 只重建 rotary embedding 缓冲区,不恢复 pos_embed。

值得快速精读,尤其适合维护多模态测试与 HF runner 的工程师。亮点在于:一是用最小化 instrumentation 将 flaky 问题精确定位到 transformers 加载阶段;二是用 assert restored 保证 workaround 在未来模型变化时快速失效而不是静默出错;三是明确“上游修复后 revert”的临时补丁策略,值得借鉴。

讨论亮点

review 讨论不多且没有代码评审注释。核心讨论是维护者 DarkLight1337 提出的策略:“Let's fix CI first and revert once the issue has been fixed upstream”,即把本改动视为针对 transformers 缺陷的临时 workaround,待上游修复后回滚。AndreasKaratzas 审核后批准(LGTM)。claude[bot] 提示该 PR 来自 fork,自动 review 被禁用,需维护者手动触发。

实现拆解

  1. 根因定位:作者用 standalone 脚本对比 vLLM 与 HF 加载后的 resampler.pos_embed,并用 _set_2d_pos_cache 重跑验证,确认问题发生在 transformers 权重加载阶段,而非前向计算。
  2. 新增 helper:在 tests/models/multimodal/generation/vlm_utils/model_utils.py 新增 _restore_resampler_pos_cache,遍历 hf_model.model.modules(),对具备 _set_2d_pos_cache 的模块以 module.max_sizemodule.pos_embed.device 重算位置表,并用 assert restored 兜底,防止模型结构调整后静默失效。
  3. 接入 patch 流程:在 minicpmv_26_patch_hf_runner 中,于 patch generate 之前调用 _restore_resampler_pos_cache,确保 HF 参考解码使用正确的位置表。
  4. 验证:6 个用例(3 个 multi-image + 3 个 single-image)循环 20 次共 120 次执行全部通过;无配置文件、schema 或生产代码改动。
文件 模块 状态 重要度
tests/models/multimodal/generation/vlm_utils/model_utils.py 测试工具 modified 5.07

关键符号

_restore_resampler_pos_cache minicpmv_26_patch_hf_runner

关键源码片段

tests/models/multimodal/generation/vlm_utils/model_utils.py test-coverage

唯一变更文件。新增 _restore_resampler_pos_cache 并在 minicpmv_26_patch_hf_runner 中调用,修复 HF 加载时 pos_embed 被置为未初始化内存导致的测试 flaky。

def _restore_resampler_pos_cache(hf_model: HfRunner) -> None:
    """Recompute the resampler's 2D sin/cos position cache after loading.    `from_pretrained` materializes non-persistent buffers as uninitialized
    memory, leaving `pos_embed` as zeros or NaN instead of the values computed
    in `__init__`.
    """
    restored = 0
    for module in hf_model.model.modules():
        if not hasattr(module, "_set_2d_pos_cache"):
            continue
        # 在 buffer 当前所在设备上重算位置缓存,等价于重新执行 __init__ 里的初始化逻辑
        module._set_2d_pos_cache(module.max_size, module.pos_embed.device)
        restored += 1
    # 若模型结构变化导致找不到 resampler,立即失败而不是静默通过
    assert restored, "no resampler pos cache found to restore"
​
​
def minicpmv_26_patch_hf_runner(hf_model: HfRunner) -> HfRunner:
    # 先恢复被 transformers 破坏的 pos cache,再 patch generate
    _restore_resampler_pos_cache(hf_model)
​
    orig_generate = hf_model.model.generate
​
    def _generate(self, *args, image_sizes=None, **kwargs):
        return orig_generate(*args, decode_text=False, **kwargs)
​
    hf_model.model.generate = types.MethodType(_generate, hf_model.model)
​
    return hf_model

评论区精华

上游修复后的临时策略 设计

DarkLight1337 表示 “Let's fix CI first and revert once the issue has been fixed upstream”,说明本修复是针对 transformers 加载缺陷的临时 workaround。

结论:先合并修复 CI,等待上游 transformers 修复后 revert 本测试补丁。 · 已解决

维护者批准 other

AndreasKaratzas 审核后给出 APPROVED,评论为 LGTM。

结论:PR 获得维护者批准并合并。 · 已解决

Fork PR 的自动 review 被禁用 other

claude[bot] 指出该 PR 来自 fork,自动 review 被禁用,维护者可评论 @claude review 触发一次性 review。

结论:未触发自动 review,改由人工 review 完成。 · 已解决

风险与影响

本次变更全部落在测试代码中,生产代码零接触,回归风险极低。但该 workaround 依赖 transformers 对 non-persistent buffer 的处理行为,transformers 版本升级后可能不再需要或不再匹配;assert restored 能保证在模型结构调整或 _set_2d_pos_cache 消失时快速失败,避免静默通过。若 MiniCPM-V 远程代码签名变化、或在非 CUDA 设备上执行,helper 中 .device 传递逻辑需保持正确。整体属于低风险、高可观测性的测试侧修复。

影响范围限定在多模态测试的 HF runner 参考路径,特别是 minicpmv_26 的 6 个生成用例;修复后 Extended Generation 3 TG 不再因 HF 全 NaN 或 hf/vllm 不一致而误报。对 vLLM 推理、配置、性能无任何影响。对团队而言,该 PR 提供了一个应对第三方库加载缺陷的测试侧补丁模式,并与 #51427 共同恢复同一 TG 的 CI 稳定性。

纯测试路径改动 依赖 transformers 内部行为 上游修复后需 revert

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论