Prhub

#43791 Fix early CUDA init

原始 PR 作者 hmellor 合并时间 2026-05-28 00:30 文件变更 5 提交数 1 评论 5 代码增减 +12 / -21

执行摘要

修复因 eager import 导致的 CUDA 驱动提前初始化

commit adaa5e455a 让 test_full_graph[facebook/opt-125m-model_kwargs0-2] 等测试失败,报错 RuntimeError: CUDA driver initialization failed。原因是之前为 DeepSeek V4 添加的 nvidia/ops/init.py 导入了 cutedsl 模块,而 cutedsl 模块在顶层 import cutlass/cuda.bindings.driver,导致 CUDA 驱动在 fork 子进程之前就被初始化。

此 PR 是修复 CI 的关键修复,建议合并。其设计决策(避免在 init.py 中导出可能引入副作用的大模块)值得其他模块借鉴。

讨论亮点

mgoin 提问:'Why are these inits even getting importing if we aren't using deepseekv4?' hmellor 解释:test_full_graph 会遍历所有模型,对每个模型调用 is_quant_method_supported,该检查会导致 DSv4 模块被导入,从而触发 CUDA 初始化。WoosukKwon 表示:'I think we should also remove the weird model initialization though',暗示后续还需要清理这种奇怪的模型初始化逻辑。

实现拆解

  1. 移除 __init__.py 的导出importvllm/models/deepseek_v4/nvidia/ops/__init__.py):删除所有的 from-import 语句和 all,只保留模块文档字符串,避免任何人导入该包时触发 cutedsl 模块的顶层 import。
  2. 将调用点改为直接 import 叶子模块:在 vllm/models/deepseek_v4/compressor.pyvllm/models/deepseek_v4/nvidia/model.pyvllm/models/deepseek_v4/common/ops/fused_indexer_q.pyvllm/models/deepseek_v4/common/ops/cache_utils.py 中,将原来从 .nvidia.ops 的导入改为直接从具体的子模块导入(如 .nvidia.ops.sparse_attn_compress_cutedsl),确保只在需要时才加载 cutedsl 内核代码。
文件 模块 状态 重要度
vllm/models/deepseek_v4/nvidia/ops/__init__.py DeepSeek V4 modified 5.74
vllm/models/deepseek_v4/compressor.py DeepSeek V4 modified 5.96
vllm/models/deepseek_v4/nvidia/model.py DeepSeek V4 modified 5.1
vllm/models/deepseek_v4/common/ops/fused_indexer_q.py DeepSeek V4 modified 4.14
vllm/models/deepseek_v4/common/ops/cache_utils.py DeepSeek V4 modified 3.96

关键源码片段

vllm/models/deepseek_v4/nvidia/ops/__init__.py infrastructure

核心修改:清空 export import,避免任何人导入本包时触发 cutedsl 模块的顶层 import,从而防止 CUDA 驱动提前初始化。

# vllm/models/deepseek_v4/nvidia/ops/__init__.py
"""
These modules import ``cutlass``/``cutedsl`` at module top level, so they must
not be imported on non-CUDA platforms. Callers should gate on
``vllm.utils.import_utils.has_cutedsl()`` before importing from here.This ``__init__`` deliberately imports nothing: re-exporting the cutedsl
modules here would eagerly ``import cutlass`` (initializing the CUDA driver)
for anyone who imports ``vllm.models.deepseek_v4``, breaking forked subprocesses.
Import the leaf modules directly under a ``has_cutedsl()``/``is_cuda()`` gate.
"""
# 不在此导出任何符号,避免顶层 import 触发 CUDA 驱动初始化
vllm/models/deepseek_v4/compressor.py data-contract

修改了 cutedsl 内核的导入路径,从包级导入改为叶子模块导入,确保只在需要时加载。

# 在 vllm/models/deepseek_v4/compressor.py 的 forward 方法中
if current_platform.is_cuda():
    # NVIDIA GPUs.
    if self.head_dim == 512:
        # 改为直接从具体子模块导入,避免触发 __init__.py 中的顶层 import
        from .nvidia.ops.sparse_attn_compress_cutedsl import (
            compress_norm_rope_store_cutedsl,
        )
        compress_norm_rope_store_fn = compress_norm_rope_store_cutedsl
    else:
        compress_norm_rope_store_fn = compress_norm_rope_store_triton

评论区精华

为何引入 DSv4 会导致 test_full_graph 失败 question

mgoin 问为什么不需要 DSv4 时却导入了它的模块。hmellor 解释 test_full_graph 遍历所有模型并调用 is_quant_method_supported。

结论:确认是因为之前 __init__.py 的 eager import 导致 CUDA 驱动在 fork 前被初始化。 · 已解决

是否需要进一步清理模型初始化逻辑 设计

WoosukKwon 表示应该移除奇怪的模型初始化逻辑。

结论:未解决,但作为后续改进点。 · unresolved

风险与影响

本 PR 修改了多个文件的导入路径,可能导致部分依赖旧导入路径的代码(如未更新导入的插件或外部工具)失效。但所有修改都在同一仓库内,且已有 review 确认,风险较低。

影响范围较小,主要修复了 CI 测试失败问题,确保了 v0.22.0 版本的稳定。对用户无直接影响,对开发者来说,后续使用 DeepSeek V4 相关模块时,需要确保调用点正确导入叶子模块。

导入路径变更 缺少测试覆盖

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论