Prhub

#49484 Fix GLM-4.1V video placeholder token ID handling.

原始 PR 作者 aarushjain29 合并时间 2026-07-25 03:35 文件变更 2 提交数 2 评论 1 代码增减 +24 / -43

执行摘要

修复 GLM-4.1V 视频占位符 token ID 错误

ROCm 多模态 CI 中测试 test_custom_inputs_models[glm4_1v-video-test_case7] 失败。问题根源是视频帧占位符使用了 video_token_id 而非 image_token_id,导致生成的描述与 HuggingFace 不一致(例如 "book on floor" 对比 "laptop on bed")。

建议精读核心改动,尤其是 _call_hf_processor 中的 token 映射逻辑和 _get_video_frame_embed_token_id 的抽取,这是管理 token ID 一致性的良好实践。

讨论亮点

此次 review 没有实质讨论。AndreasKaratzas 指出该 PR 与 #49220 内容相同,因之前合并导致 main 损坏而迁移至此,且已被两位 committer 批准。Claude bot 因 PR 来自 fork 而跳过自动审查。

实现拆解

1. 提取 _get_video_frame_embed_token_id 方法

vllm/model_executor/models/glm4_1v.py 中新增 _get_video_frame_embed_token_id 方法,根据处理器类型返回正确的 token ID:对于 Glm4vProcessorTRANSFORMERS_WITH_GA 时返回 image_token_id,否则返回 video_token_id

2. 修改 _construct_video_placeholder

_get_video_frame_embed_token_id 替换原有的硬编码条件,确保 GLM-4.1V 视频帧占位符使用 image_token_id

3. 修改 _call_hf_processor

仅在 _get_video_frame_embed_token_id 返回 image_token_id 时(即 GLM-4.1V),对视频块内的 image_token_id 执行替换为 video_token_id 的映射,以兼容 HuggingFace 的文本回馈路径。同时新增反向映射,将处理后的 video_token_id 恢复为 image_token_id,以保持一致的最终 prompt。

4. 调整 get_image_replacement 系列函数

get_image_replacement_glm4v 中的 token ID 从 video_token_id 改为 image_token_id,简化条件逻辑。

5. 更新测试

tests/models/multimodal/processing/test_glm4_1v.pytest_processor_override 改为直接使用 hf_processor.image_token_id 进行计数,移除多余的 tokenizer 变量。

文件 模块 状态 重要度
vllm/model_executor/models/glm4_1v.py 模型执行 modified 8.77
tests/models/multimodal/processing/test_glm4_1v.py GLM 1v modified 4.47

关键符号

_get_video_frame_embed_token_id get_image_replacement_glm4v _construct_video_placeholder _call_hf_processor

关键源码片段

vllm/model_executor/models/glm4_1v.py data-contract

核心源码文件,包含所有逻辑变更:新增 `_get_video_frame_embed_token_id` 方法,修改 `_construct_video_placeholder` 和 `_call_hf_processor` 以及 `get_image_replacement_glm4v` 等函数。

def _get_video_frame_embed_token_id(self, hf_processor: object) -> int:
    # GLM-4.1V (Glm4vProcessor) 和带 GA 的 GLM 模型使用 image_token_id 作为帧嵌入
    if isinstance(hf_processor, Glm4vProcessor) or TRANSFORMERS_WITH_GA:
        return hf_processor.image_token_id
    # 其他 GLM 模型使用 video_token_id
    return hf_processor.video_token_id

这个新增方法将之前分散的条件逻辑集中管理,使得代码意图清晰。在 _call_hf_processor 中,条件映射逻辑如下:
# 仅在帧嵌入使用 image_token_id 时,才需要在 HF 处理后交换 token
swap_video_frame_tokens = frame_embed_token_id == processor.image_token_id
if swap_video_frame_tokens:
    input_ids[input_ids == processor.image_token_id] = processor.video_token_id
# ... 后续处理 ...
# 最后再将 video_token_id 映射回 image_token_id
if swap_video_frame_tokens:
    input_ids[input_ids == processor.video_token_id] = processor.image_token_id

评论区精华

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

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

风险与影响

低风险。变更集中在 GLM-4.1V 的视频占位符生成路径,通过提取方法和条件映射隔离了影响。但仍需注意以下风险:

  • 回归风险:_call_hf_processor 中的条件 token 映射可能影响混合图文输入。
  • 兼容风险:依赖 TRANSFORMERS_WITH_GA 标志,若 transformers 版本变化可能改变行为。

影响面较小,仅涉及 GLM-4.1V 模型的多模态处理。修复后,视频帧占位符与 HuggingFace 一致,生成描述准确性得到提升。对系统性能无影响。

依赖 transformers 版本标志 TRANSFORMERS_WITH_GA

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论