Prhub

#50097 [XPU] fix_test_worker_memory_snapshot_for_xpu

原始 PR 作者 mayuyuace 合并时间 2026-09-16 11:05 文件变更 1 提交数 4 评论 3 代码增减 +21 / -6

执行摘要

修复 worker 内存快照测试的 XPU 兼容性

PR body 明确说明:"Dynamically select worker class ([XPUWorker] vs [Worker]) and patch target based on [current_platform.is_xpu()], so the test works on both CUDA and XPU. Rename label "nccl_all_reduce" to "dist_all_reduce", since XPU uses XCCL, not NCCL; the label should be backend-agnostic." 原测试硬编码 GPU Worker 和 gpu_worker 模块符号,在 Intel GPU 平台上会因 worker 类不匹配而失败,且操作标签绑定 NCCL 命名,与 XPU 的 XCCL 后端语义不符。

不值得精读——这是单一测试文件的平台适配。但有两个小决策可供 XPU 移植类测试参考:一是用 current_platform.is_xpu() 做运行时分支而非复制整个测试文件;二是把 NCCL 专属标签改为后端无关的 dist_all_reduce,保持测试语义中立。若后续维护,建议顺手确认 xpu_worker.init_worker_distributed_environment 与 GPU 版本是否为同一实现,消除 original 函数引用错配的隐患。

讨论亮点

该 PR 几乎没有实质技术讨论:claude[bot] 自动回复说明 fork 来源的 PR 默认禁用自动评审,需维护者手动触发;维护者 jikunshang 直接 APPROVED,无文字评论;Issue 评论区仅有 @ 提人、/ci run 触发 Buildkite CI #89220 的操作记录。未发现争议点或未解决疑虑。

实现拆解

实现分 4 步,全部集中在 tests/v1/worker/test_worker_memory_snapshot.py:

  1. 引入平台探测:顶部新增 from vllm.platforms import current_platform 导入,为后续分支选择提供平台判断入口。
  2. 平台分支选择 worker 类与 patch 目标:在 worker_process 内部,根据 current_platform.is_xpu() 决定 worker 类——XPU 分支从 vllm.v1.worker.xpu_worker 导入 XPUWorker,patch 目标字符串指向 vllm.v1.worker.xpu_worker.init_worker_distributed_environment;否则使用原 Worker 与 gpu_worker 路径。随后用统一的 worker_cls(...) 创建实例。
  3. patch 目标参数化:init_patch 从硬编码字符串改为使用变量 init_patch_target,side_effect 仍是 make_operation_tracker("init_distributed", original_init_worker) 包装器,保证记录操作后仍转发到原始函数。
  4. 操作标签后端无关化:all_reduce_patch 的跟踪标签从 nccl_all_reduce 改为 dist_all_reduce,并在测试断言处同步改名,避免语义绑定到 NVIDIA NCCL 实现。

测试逻辑本身不变:仍通过 multiprocessing 启动 2 个 rank,patch 三个关键操作(分布式初始化、内存快照、all_reduce),断言顺序为 init_distributed < dist_all_reduce < memory_snapshot。无配置、schema 或部署配套改动。

文件 模块 状态 重要度
tests/v1/worker/test_worker_memory_snapshot.py 内存快照 modified 4.76

关键符号

worker_process test_init_distributed_is_called_before_memory_snapshot

关键源码片段

tests/v1/worker/test_worker_memory_snapshot.py test-coverage

本次变更唯一文件,负责让 worker 内存快照顺序测试在 XPU 平台可运行:动态选择 XPUWorker/Worker 与 patch 目标,并将操作标签改为后端无关的 dist_all_reduce。

def worker_process(
    rank: int,
    world_size: int,
    distributed_init_method: str,
    queue: Queue,
    error_queue: Queue,
):
    """Worker 进程:初始化 GPU/XPU worker 并跟踪关键操作顺序。"""
    global _QUEUE
    _QUEUE = queue
​
    try:
        # 设置分布式环境变量
        os.environ["RANK"] = str(rank)
        os.environ["LOCAL_RANK"] = str(rank)
        os.environ["WORLD_SIZE"] = str(world_size)
​
        # 使用 dummy 权重创建小模型配置,避免真实下载
        vllm_config = EngineArgs(
            model="facebook/opt-125m", tensor_parallel_size=2, load_format="dummy"
        ).create_engine_config()
​
        # 根据平台选择 worker 类与 patch 目标:
        # XPU 使用 XPUWorker 与 XCCL,CUDA 使用 Worker 与 NCCL
        if current_platform.is_xpu():
            from vllm.v1.worker.xpu_worker import XPUWorker
​
            worker_cls = XPUWorker
            init_patch_target = (
                "vllm.v1.worker.xpu_worker.init_worker_distributed_environment"
            )
        else:
            worker_cls = Worker
            init_patch_target = (
                "vllm.v1.worker.gpu_worker.init_worker_distributed_environment"
            )
​
        # 创建 worker 实例
        worker = worker_cls(
            vllm_config=vllm_config,
            local_rank=rank,
            rank=rank,
            distributed_init_method=distributed_init_method,
        )
​
        # 记录原始函数,供 mock wrapper 在记录后转发调用
        original_init_worker = init_worker_distributed_environment
        original_memory_snapshot_init = MemorySnapshot.__init__
        original_all_reduce = torch.distributed.all_reduce
​
        # 用最小侵入的 patch 记录各操作发生的顺序
        init_patch = patch(
            init_patch_target,
            side_effect=make_operation_tracker(
                "init_distributed", original_init_worker
            ),
        )
        memory_patch = patch.object(
            MemorySnapshot,
            "__init__",
            make_operation_tracker("memory_snapshot", original_memory_snapshot_init),
        )
        # 标签使用后端无关的 dist_all_reduce:XPU 走 XCCL,并非 NCCL
        all_reduce_patch = patch(
            "torch.distributed.all_reduce",
            side_effect=make_operation_tracker("dist_all_reduce", original_all_reduce),
        )
​
        with (
            init_patch,
            memory_patch,
            all_reduce_patch,
            set_current_vllm_config(vllm_config),
        ):
            # 此处验证:分布式初始化必须先于首次内存快照
            worker.init_device()
            worker.load_model()
​
        # 成功信号
        queue.put(("success", rank))
​
    except Exception as e:
        error_queue.put((rank, str(e), type(e).__name__))
        raise

评论区精华

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

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

风险与影响

整体风险很低(纯测试文件改动),但有 3 点值得注意:

  1. original 函数引用可能错配:original_init_worker 固定从 vllm.v1.worker.gpu_worker 顶层导入(文件头 import),而 XPU 分支 patch 的目标是 vllm.v1.worker.xpu_worker.init_worker_distributed_environment。若 xpu_worker 模块是独立实现而非 re-export 同一函数对象,则包装器记录后实际调用的是 GPU 版本初始化函数,可能跳过 XPU 特有的初始化逻辑。该问题不影响顺序断言,但会削弱测试对 XPU 路径的真实性验证。
  2. all_reduce 覆盖完整性:测试假设 torch.distributed.all_reduce 是 all_reduce 的唯一入口。若 XPU/XCCL 路径存在绕过 torch 封装的直接通信调用,rank_ops.index("dist_all_reduce") 会抛 ValueError 导致测试失败。
  3. 平台分支覆盖不全:else 分支默认走 CUDA Worker,若在 CPU 等非 CUDA 非 XPU 平台运行(需满足 accelerator.device_count() >= 2 的 skipif 条件),可能创建不匹配的 worker 类,影响有限。

对最终用户无直接功能影响,属 CI/测试基建层变更。对系统而言,解锁了 XPU 平台上 worker 初始化顺序(分布式环境先于首次内存快照)的回归测试覆盖,可防止未来 XPU worker 改动破坏该关键顺序。对团队而言,为 Intel GPU 支持补充了与 CUDA 对齐的测试保障,并为后续 XPU 移植类测试提供了"平台分支 + 后端无关标签"的参考模式。影响范围小,仅涉及 single 测试文件。

测试专用改动,风险低 original 函数引用可能错配 平台分支未覆盖 CPU 等场景

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论