Prhub

#42162 Fix Molmo2 image token metadata

原始 PR 作者 hqhq1025 合并时间 2026-05-11 09:19 文件变更 2 提交数 2 评论 15 代码增减 +94 / -10

执行摘要

修复 Molmo2 图像令牌元数据与 HF 处理器不匹配

修复Issue #38660中MolmoWeb模型在Triton注意力内核的CUDA断言错误。根本原因是_merge_multimodal_embeddings中令牌数与嵌入数不匹配,源于build_flat_image_bool_length低分辨率令牌布局硬编码。PR body指出:prompt image placeholder tokens: 550, multimodal image embeddings: 536,缺少14个低分辨率行列令牌。

值得精读的设计决策:如何将HF处理器配置参数传递到vLLM的底层令牌生成函数,保持向后兼容的默认值。讨论中关于测试验证的方法(TDD, 回归测试确认)值得借鉴。

讨论亮点

主要讨论集中于测试验证。DarkLight1337询问新测试是否能在修复前失败,作者确认采用TDD流程:先添加测试观察到失败,再应用修复。作者还提供了lm-eval结果证明对标准Molmo2-8B无回归,以及WebVoyager性能对比(45.55% vs 46.05%)表明修复接近官方路径。

实现拆解

步骤:

  1. 修改build_flat_image_bool_length签名,新增三个参数(image_use_col_tokens, use_single_crop_col_tokens, use_single_crop_start_token),默认值保持与之前行为一致(True, None, True)。
  2. 根据这些参数调整lengths计算(加入low_res_extrahigh_res_extra)。
  3. 重写低分辨率块生成逻辑,使用循环构造行令牌并重复,而非之前的平坦补丁填充。
  4. 在高分辨率块中条件化插入image_col_id
  5. 在调用点patched_call中从HF处理器传递这些标志。
    新增测试文件验证MolmoWeb风格配置和禁用列令牌场景。
文件 模块 状态 重要度
vllm/model_executor/models/molmo2.py 模型层 modified 6.93
tests/models/multimodal/processing/test_molmo2.py 测试 added 6.71

关键符号

build_flat_image_bool_length test_build_flat_image_bool_length_matches_molmoweb_processor_tokens test_build_flat_image_bool_length_respects_disabled_col_tokens

关键源码片段

tests/models/multimodal/processing/test_molmo2.py test-coverage

新增测试文件,验证修复后的函数行为:测试 MolmoWeb 风格配置的令牌计数(550 个令牌,28 个列令牌)和禁用列令牌场景(45 个令牌,0 个列令牌),确保回归覆盖。

from types import SimpleNamespace
import torch
from vllm.model_executor.models.molmo2 import build_flat_image_bool_lengthdef test_build_flat_image_bool_length_matches_molmoweb_processor_tokens():
    # 模拟 MolmoWeb 的处理器配置:use_single_crop_start_token=False
    hf_config = SimpleNamespace(
        image_patch_id=151938,
        low_res_image_start_token_id=151940,
        image_start_token_id=151936,
        image_col_id=151939,
        image_end_token_id=151937,
    )
    image_grids = torch.tensor([[14, 14, 14, 23]], dtype=torch.long)
​
    image_tokens, num_image_tokens = build_flat_image_bool_length(
        image_grids, hf_config,
        image_use_col_tokens=True,
        use_single_crop_col_tokens=None,
        use_single_crop_start_token=False,
    )
​
    # 预期:总共 550 个令牌,其中 28 个列令牌
    assert num_image_tokens.tolist() == [550]
    assert len(image_tokens) == 550
    assert image_tokens[0].item() == hf_config.image_start_token_id
    assert (image_tokens == hf_config.image_col_id).sum().item() == 28def test_build_flat_image_bool_length_respects_disabled_col_tokens():
    # 测试禁用列令牌且启用低分辨率起始令牌的场景
    hf_config = SimpleNamespace(
        image_patch_id=151938,
        low_res_image_start_token_id=151940,
        image_start_token_id=151936,
        image_col_id=151939,
        image_end_token_id=151937,
    )
    image_grids = torch.tensor([[2, 3, 5, 7]], dtype=torch.long)
​
    image_tokens, num_image_tokens = build_flat_image_bool_length(
        image_grids, hf_config,
        image_use_col_tokens=False,
        use_single_crop_col_tokens=False,
        use_single_crop_start_token=True,
    )
​
    # 预期:总共 45 个令牌,0 个列令牌,起始令牌为 low_res 类型
    assert num_image_tokens.tolist() == [45]
    assert len(image_tokens) == 45
    assert image_tokens[0].item() == hf_config.low_res_image_start_token_id
    assert (image_tokens == hf_config.image_col_id).sum().item() == 0

评论区精华

测试验证是否能在修复前失败 测试

DarkLight1337 询问新测试是否能在未修复代码上失败。作者回应采用 TDD 流程:先添加测试并观察到失败(536 vs 550 令牌,缺失列令牌),再应用修复。并提供了具体失败断言。

结论:确认测试能有效捕获回归。 · 已解决

对标准 Molmo2-8B 的回归检查 测试

DarkLight1337 要求运行多模态 lm-eval 确认无回归。作者提供了 ChartQA 上的 acc_norm 对比(0.5365 vs 0.5365)和 WebVoyager 性能对比(45.55% vs 46.05%)。

结论:无退化,对标准 Molmo2-8B 行为一致。 · 已解决

风险与影响

主要风险是向后兼容性:新增参数有默认值(True/None/True),未传递时行为与之前保持一致,但需要确认所有调用点已更新(当前仅patched_call一处)。另一个风险是数值变动可能影响其他Molmo2变体(如视频处理路径build_flat_video_bool_length未修改,视频未受影响)。测试覆盖了常见和禁用列令牌场景,但缺少端到端模型集成测试。

直接影响Molmo2系列模型用户,特别是MolmoWeb变体(如WebVoyager任务)。修复使vLLM与Hugging Face处理器语义对齐,解锁之前因CUDA错误无法使用MolmoWeb模型的场景。对标准Molmo2-8B用户无影响(行为一致)。范围限于Molmo2多模态处理,不涉及其他模块。

核心路径变更 数据契约调整 缺少端到端集成测试

关联 Issue

#38660 [Bug]: CUDA assert in triton attention for MolmoWeb models (Molmo2 architecture with different max_position_embeddings)

完整报告

参与讨论