Prhub

#48015 [ROCm][CI] Avoid HIP init at config time via lazy aiter import in Quark OCP-MX

原始 PR 作者 music-dino 合并时间 2026-07-17 00:47 文件变更 1 提交数 5 评论 8 代码增减 +29 / -21

执行摘要

延迟导入 aiter 避免 ROCm HIP 初始化导致 fork/spawn 问题

PR 指出在 ROCm 上运行模型初始化测试时,V1EngineCore._initialize_kv_caches 被 monkeypatch 后无法生效,原因是 parent 进程中 HIP 在 LLM() 构造时被初始化,导致引擎只能 spawn 而非 fork。根本链路是 ModelConfig._verify_quantization 导入了 QuarkConfig,进而模块级导入了 aiter 并调用了 torch.cuda.current_device() 初始化 HIP。

建议合并此 PR。它修复了明确的 bug,设计决策合理(延迟导入以避免副作用),且通过了 reviewer 的审核。值得其他可能需要避免启动时初始化 GPU 的模块借鉴。

讨论亮点
  1. 全局变量 _AITER_FOUND 的争议:作者最初引入了一个模块级全局变量缓存 is_aiter_found_and_supported() 的结果,reviewer AndreasKaratzas 认为应复用已有的 is_aiter_found_and_supported() 函数本身,避免额外全局状态。作者接受并移除了该变量。
  2. 警告信息准确性问题:reviewer fxmarty-amd 指出修改后的警告信息错误声称 aiter 不可用时无法加速,但实际上代码会回退到仿真模式,因此加速只是不可用而不是完全不可用。作者承认并更新了警告文本。

实现拆解

  1. 修改导入语句:将 from vllm._aiter_ops import rocm_aiter_ops 改为同时导入 is_aiter_found_and_supported,该函数通过 find_spec 检查 aiter 是否可用,不执行 aiter 自身代码,因此不会触发 HIP 初始化。
  2. 替换 try-except 为条件分支:将原先的 try: ... except (ImportError, AttributeError, RuntimeError) 结构替换为 if is_aiter_found_and_supported(): ... elif current_platform.is_rocm(): ...,使代码逻辑更清晰。
  3. 延迟导入 aiter 内核:将 from aiter.ops.shuffle ... 等模块级导入移到 gemm_with_dynamic_quant 函数内部,仅在真正需要时导入 aiter,此时 HIP 已经由 PyTorch 正常初始化,符合预期。
  4. 调整异常路径的日志信息:当 aiter 不可用时,日志提示回退到仿真模式(原日志错误地声称不可用),并在检查 _verify_quantization 时使用 is_aiter_found_and_supported() 而不是检查 dynamic_mxfp4_quant 等全局变量。
文件 模块 状态 重要度
vllm/model_executor/layers/quantization/quark/schemes/quark_ocp_mx.py 量化层 modified 7.11

关键符号

gemm_with_dynamic_quant is_aiter_found_and_supported

关键源码片段

vllm/model_executor/layers/quantization/quark/schemes/quark_ocp_mx.py data-contract

核心变更文件,修改导入方式和控制流,实现延迟导入 aiter 以规避 HIP 初始化。

# vllm/model_executor/layers/quantization/quark/schemes/quark_ocp_mx.py# ...
from vllm._aiter_ops import is_aiter_found_and_supported, rocm_aiter_ops
# ...# NOTE: Do not import aiter at module scope. Importing aiter eagerly initializes HIP
# which can force the engine core to spawn instead of fork.
# is_aiter_found_and_supported() checks platform + arch + library availability via
# find_spec/amdsmi, so it stays HIP-free.
# Actual aiter imports are deferred to the functions/methods that need them,
# where HIP initialization is expected.
if is_aiter_found_and_supported():
    from vllm.utils.torch_utils import direct_register_custom_op
​
    def gemm_with_dynamic_quant(
        x: torch.Tensor,
        weight: torch.Tensor,
        weight_scale: torch.Tensor,
        rocm_use_aiter_fp4_asm_gemm: bool = False,
        out_dtype: torch.dtype | None = torch.bfloat16,
        x_scales: torch.Tensor | None = None,
    ) -> torch.Tensor:
        # 延迟导入,仅在需要时加载 aiter,此时 HIP 已由 PyTorch 初始化
        from aiter.ops.triton.gemm_afp4wfp4 import (
            gemm_afp4wfp4,
            gemm_afp4wfp4_preshuffled_weight_scales,
        )
        from aiter.ops.triton.quant import dynamic_mxfp4_quant
​
        if rocm_use_aiter_fp4_asm_gemm:
            from aiter import gemm_a4w4, per_1x32_f4_quant_hip
        # ... 函数逻辑不变 ...
​
    # ... custom op registration ...
elif current_platform.is_rocm():
    logger.warning(
        "AITER is not found or not supported on the current platform, "
        "QuarkOCP_MX will fall back to emulation."
    )class QuarkOCP_MX(QuarkScheme):
    # ... 类定义,在需要时使用 is_aiter_found_and_supported() 判断,而非全局变量

评论区精华

使用全局变量 _AITER_FOUND 还是直接调用 is_aiter_found_and_supported 设计

AndreasKaratzas 认为不应引入模块级全局变量,应直接使用已有的 is_aiter_found_and_supported 函数;作者最初使用 find_spec 并缓存为 _AITER_FOUND,后接受建议移除。

结论:移除全局变量 _AITER_FOUND,直接每次调用 is_aiter_found_and_supported。 · 已解决

警告信息准确性 正确性

fxmarty-amd 指出当 aiter 不可用时,警告称加速不可用,但实际上代码会回退到仿真模式,仍有可用的功能。作者同意并更新了警告文本。

结论:更新警告为 "QuarkOCP_MX will fall back to emulation",更准确描述行为。 · 已解决

风险与影响

主要风险在于延迟导入可能引入性能影响:每次调用 gemm_with_dynamic_quant 都会重新执行导入语句。但 Python 导入机制会缓存模块,因此实际影响很小。另一个风险是 is_aiter_found_and_supported() 的语义是否与原来的 try-except 完全一致;但该函数本身设计用于此目的,风险较低。

直接影响:修复了 ROCm 平台上 4 个模型初始化测试的失败问题。间接影响:所有使用 QuarkOCP-MX 量化的模型在 ROCm 上的初始化和配置流程更稳定,不再因为 HIP 过早初始化导致进程启动方式改变。此外,该模式(延迟导入)可作为其他类似问题的参考。

缺少测试配套 导入语义变更

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论