Prhub

#39167 [DP][Ray] Pin DP control bundle to same node as first GPU bundle

原始 PR 作者 shaharmor98 合并时间 2026-04-24 01:21 文件变更 1 提交数 6 评论 6 代码增减 +27 / -2

执行摘要

修复多节点 DP 中 Ray control bundle 漂移导致 actor 错位

修复多节点 Data Parallel 服务中 Ray 后端的一个 bug:在多节点 span DP 布局中,Ray placement group 的 control bundle 没有节点约束,导致 engine actor 可能被调度到与第一个 GPU bundle 无关的节点,造成工作节点拓扑错位和启动不稳定。

值得精读。该 PR 展示了如何通过 Ray placement group 的节点亲和性选项解决分布式中 actor 调度错位问题,设计决策清晰,注释详细,适合作为分布式调度问题的参考。

讨论亮点

gemini-code-assist[bot]:辅助函数 make_control_bundleget_bundle_node_ip 定义在局部函数内,建议提升为模块级或在 CoreEngineActorManager 中作为静态方法,以便在 add_dp_placement_groups 中复用,确保弹性伸缩时行为一致。

tomeras91:指出只有 span 策略会触发 bug,fill/strictSTRICT_PACK 已保证同节点,但同意添加注释和一致性改动,方便未来维护。

实现拆解

  1. vllm/v1/engine/utils.py 中添加两个模块级辅助函数 _make_control_bundle(node_ip)_get_bundle_node_ip(bundle),分别用于创建带节点亲和性的 CPU bundle 和从现有 bundle 中提取节点 IP。

  2. create_dp_placement_groupsspan 策略分支中,使用 _get_bundle_node_ip(collected_bundles[0]) 获取第一个 GPU bundle 的节点 IP,然后调用 _make_control_bundle(control_node_ip) 替代原先的无约束 {"CPU": 1.0},确保 control bundle 与 GPU bundle 位于同一节点。

  3. fill 策略分支中,同样使用 _make_control_bundle(node_ip) 替代,并添加注释说明 STRICT_PACK 已保证所有 bundle 在同节点,此处仅为一致性和未来防护而添加。

  4. 本次改动未覆盖 add_dp_placement_groups 方法(用于弹性伸缩),review 中提出了但未在本次实现,已记录为后续改进。

文件 模块 状态 重要度
vllm/v1/engine/utils.py DP 调度 modified 7.38

关键符号

_make_control_bundle _get_bundle_node_ip

关键源码片段

vllm/v1/engine/utils.py core-logic

唯一变更文件,包含核心 fix:添加辅助函数并修改 placement group 构造逻辑

def _make_control_bundle(node_ip: str) -> dict[str, float]:
    # The engine actor is scheduled on the final CPU-only bundle. Keep that
    # bundle colocated with the group's first GPU bundle so the actor does not
    # float to an unrelated node and reorder worker ranks away from the
    # advertised DP bootstrap host.
    return {"CPU": 1.0, "node:" + node_ip: 0.001}
​
​
def _get_bundle_node_ip(bundle: dict[str, float]) -> str:
    for key in bundle:
        if key.startswith("node:"):
            return key.split(":", 1)[1]
    raise ValueError(f"Missing node affinity in placement bundle: {bundle}")

评论区精华

辅助函数的作用域与复用建议 设计

gemini-code-assist[bot] 建议将 make_control_bundle 和 get_bundle_node_ip 提升为模块级函数,以便在 add_dp_placement_groups 中复用,确保弹性伸缩时行为一致。

结论:作者采纳建议,最终定义为模块级函数(以 _ 开头),但未在 add_dp_placement_groups 中应用。 · 已解决

fill/strict 策略下改动的必要性 设计

tomeras91 指出只有 span 策略会触发 bug,fill/strict 因 STRICT_PACK 已保证同节点,但同意添加注释和一致性改动。

结论:添加注释说明 fill 策略下改动是冗余的,但为了一致性和未来防护保留。 · 已解决

风险与影响

低风险。改动仅影响 control bundle 创建逻辑,增加的节点亲和性是一个软约束(0.001),不会导致资源分配失败。但如果 bundle 缺少 node 键(内部逻辑错误),_get_bundle_node_ip 会抛出 ValueError,但这种情况在正常流程中不应发生。主要风险是缺少测试覆盖,无法在 CI 中验证多节点场景。

用户:修复多节点 DP 环境下 engine actor 可能错位的问题,提升启动稳定性和可靠性。系统:无性能影响,改动仅涉及 placement group 创建时的 bundle 构造。团队:需注意未来在 add_dp_placement_groups 中应用相同修复以保持一致。

缺少测试覆盖 变更影响 DP 启动流程

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论