Prhub

#45254 [MM][CG] Support ViT full CUDA graph for Ernie-4.5-VL image inference

原始 PR 作者 qyYue1389 合并时间 2026-08-06 13:04 文件变更 4 提交数 16 评论 32 代码增减 +289 / -13

执行摘要

Ernie-4.5-VL 图像推理接入 ViT CUDA Graph,编码器提速约 3.8 倍

该 PR 是 ViT Full CUDA Graph tracker #38175 的一部分,旨在将编码器(ViT)纳入 CUDA Graph 以消除图像编码阶段的内核启动与同步开销。作者引用 Qwen3-VL 的 SupportsEncoderCudaGraph 作为参考实现。PR body 中给出了明确收益:在 H100 上 encoder_forward 均值从 eager 的 20.19ms 降至 CUDA Graph 的 5.33ms(约 3.79× 加速,P99 达 5.35×)。同时通过 AI2D 与 MMStar 基准验证了精度不受影响(差异在 stderr 内),并通过 50 张图的贪婪解码验证 94% 字节级一致输出。

值得精读。该 PR 是 SupportsEncoderCudaGraph 协议的又一个落地案例,展示了如何处理无法捕获的 host-side 逻辑(resampler eager)以及如何通过 prepare_encoder_metadata 解耦图捕获与 eager 路径。对于要接入 ViT CUDA Graph 的模型开发者有很强的参考价值,尤其是固定缓冲区的填充策略与最坏情况 max_seqlen 的设计。

讨论亮点
  • shen-shanshan 在文档表格处提问:“As far as I know, this model supports video inference, does this PR support?” 作者回复确认视频推理本身支持,但视频路径在 resampler 中使用 use_temporal_conv 会改变输出 token 数,需要单独处理,故本 PR 仅图像,后续 PR 跟进。
  • shen-shanshan 指出如果仅支持图像,某些协议方法(如 get_input_modality)不需要,并引用 PR #44484;作者回复已移除。
  • shen-shanshan 询问 use_temporal_conv=False 时 resampler 是否可捕获(仅线性与激活层)。作者确认可行,但官方 ERNIE-4.5-VL-28B-A3B 配置 use_temporal_conv=True,因此 resampler 留在 eager 路径,包含在后续 PR 中。

实现拆解

  1. 拆分 metadata 计算:在 vllm/model_executor/models/ernie45_vl.py 的 Ernie4_5_VisionTransformer 中新增 prepare_encoder_metadata(),将原 forward 内联的 rotary 嵌入、cu_seqlens、max_seqlen 计算迁出,支持 max_batch_size 填充固定形状和 max_seqlen_override 最坏情况覆盖,使 eager、捕获和回放三条路径共享同一套预计算逻辑。
  2. 实现 SupportsEncoderCudaGraph 协议:Ernie4_5_VLMoeForConditionalGeneration 继承该协议,实现 get_encoder_cudagraph_config(4 个 buffer key,out_hidden_size)、get_encoder_cudagraph_budget_range(64 到 min(max_num_batched_tokens, max_model_len))、get_encoder_cudagraph_item_specs、select_encoder_cudagraph_items(按累积 patch 偏移切分 pixel_values)以及捕获输入与回放缓冲区的准备方法。捕获边界限定为 ViT,resampler 在 postprocess_encoder_output 与 encoder_eager_forward 中 eager 执行。
  3. 测试配套:在 tests/models/multimodal/generation/test_vit_cudagraph.py 中新增 ernie45_vl 配置,使用 load_format="dummy" 与 dummy_hf_overrides 缩减为 1 层文本 + 1 层视觉的随机权重,避免约 56 GiB 权重下载,在任意 CI GPU 上验证捕获/回放正确性。
  4. 示例与文档:在 examples/generate/multimodal/vision_language_offline.py 的 MODELS_SUPPORT_VIT_CUDA_GRAPH 列表加入 ernie45_vl;在 docs/design/cuda_graphs_multimodal.md 表格中登记该模型(图像 CG 支持,视频暂不支持)。
文件 模块 状态 重要度
vllm/model_executor/models/ernie45_vl.py 模型实现 modified 9.05
tests/models/multimodal/generation/test_vit_cudagraph.py 测试 modified 6.0
examples/generate/multimodal/vision_language_offline.py 示例 modified 4.18
docs/design/cuda_graphs_multimodal.md 文档 modified 1.18

关键符号

prepare_encoder_metadata forward get_encoder_cudagraph_config get_encoder_cudagraph_budget_range get_encoder_cudagraph_item_specs select_encoder_cudagraph_items prepare_encoder_cudagraph_capture_inputs prepare_encoder_cudagraph_replay_buffers

关键源码片段

tests/models/multimodal/generation/test_vit_cudagraph.py test-coverage

新增 ernie45_vl 测试配置,使用 dummy 权重与 chat template 覆盖图像场景的捕获 / 回放,验证功能正确性。

def ernie45_vl_chat_template(content: str) -> str:
    # Ernie-4.5-VL 的对话模板,将图像占位符放在用户提问之后
    return (
        f"<|begin_of_sentence|>User: {content}"
        "Picture 1:<|IMAGE_START|><|image@placeholder|><|IMAGE_END|>\n"
        "Assistant: <think></think>"
    )
​
# 在 MODEL_CONFIGS 中新增的配置条目
def _ernie45_vl_config():
    return VitCudagraphTestConfig(
        model="baidu/ERNIE-4.5-VL-28B-A3B-PT",
        # 仅图像:视频的 resampler 应用 temporal conv 改变输出 token 数,走 eager 路径
        modalities=["image"],
        image_prompt=ernie45_vl_chat_template("What is in this image?"),
        # 缩减为随机权重的 1 层文本 + 1 层视觉,任意 CI GPU 可运行且跳过约 56 GiB 下载
        vllm_runner_kwargs={
            "load_format": "dummy",
            "trust_remote_code": True,
            "revision": "refs/pr/17",
            "hf_overrides": partial(
                dummy_hf_overrides,
                model_arch="Ernie4_5_VLMoeForConditionalGeneration",
            ),
        },
    )

评论区精华

视频推理支持范围 设计

shen-shanshan 在文档表格处提问该模型支持视频但文档标为不支持。作者解释视频路径的 resampler 使用 use_temporal_conv 改变输出 token 数,需单独处理,本 PR 仅图像,后续 PR 跟进。

结论:确认仅图像支持,视频留待后续 PR;文档如实标注。 · 已解决

resampler 是否可纳入 CUDA Graph 设计

shen-shanshan 指出 use_temporal_conv=False 时 resampler 仅含线性与激活层,理论上可捕获。作者确认可行,但官方 ERNIE-4.5-VL-28B-A3B 配置 use_temporal_conv=True,故 resampler 保留 eager,后续 PR 再考虑。

结论:当前保留 eager 路径,后续 PR 可探索纳入图上。 · 已解决

图像专用协议方法冗余 设计

shen-shanshan 引用 PR 44484 建议移除仅图像场景不需要的方法(如 get_input_modality)。作者接受并移除。

结论:已移除冗余方法。 · 已解决

风险与影响

  • 数值一致性:CUDA Graph 回放使用填充后的固定缓冲区,导致 3/50 图片出现单字翻转(接近平局),字节级不完全一致,但作者论证不影响模型输出质量。
  • 仅图像路径覆盖:视频输入继续走 eager,若调用方在视频场景误启用 cudagraph_mm_encoder,可能回退或产生未预期行为(需检查运行时是否按 modality 分流)。
  • prepare_encoder_metadata 被 eager 与图路径共用,若 max_seqlen_override 或 max_batch_size 使用不当(如覆盖值小于实际),会造成注意力掩码错误或越界;当前实现依赖调用方正确传入。
  • 依赖 SupportsEncoderCudaGraph 协议和 encoder_cudagraph_defs 的演进,后续框架改动需同步维护。
  • 测试使用 dummy 权重与缩减层数,未验证真实权重下捕获/回放的数值稳定性(但作者提供了外部的精度基准)。
  • 对用户:使用 ERNIE-4.5-VL 图像推理的用户启用 cudagraph_mm_encoder 后可获得约 3.8× 编码器加速,GPU 空闲时间减少。
  • 对系统:新增一个模型接入 ViT CUDA Graph 协议,扩展了可捕获模型的覆盖范围;resampler 保持 eager,因此显存占用与 eager 路径接近,未增加图捕获池负担。
  • 对团队:确立了一种“拆分 metadata + 部分捕获”的模式,为后续视频路径与其他模型提供参考;文档登记了模型能力边界。
仅图像路径支持 resampler 保留 eager 路径 回放数值非逐位一致 依赖协议演进 测试使用 dummy 权重

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论