执行摘要
- 一句话:为 FlashInfer 通信资源添加 checkpoint 生命周期钩子
- 推荐动作:此 PR 值得精读,特别是对于需要了解 vLLM 分布式通信层次结构和 checkpoint 集成的工程师。设计上的关键决策——让 restore 依赖 CPU group 而非 GPU group——是一个重要的权衡,值得在其他类似的资源恢复场景中借鉴。此外,基类 no-op 钩子的模式使得未来扩展其他后端非常容易。
功能与动机
FlashInfer 的 all-reduce 工作空间和 all-to-all 管理器在 device memory 中持有 peer mappings / IPC handles,这些在进程 checkpoint(如 CRIU)期间必须释放。该 PR 为这些资源添加显式的 prepare(释放外部状态以便 checkpoint)和 restore(从 checkpoint 重建)钩子,使得 checkpoint 工具可以在挂起进程前调用 checkpoint_prepare,并在恢复后调用 checkpoint_restore。
实现拆解
- 定义基类钩子:在
DeviceCommunicatorBase 和 All2AllManagerBase 中添加默认 no-op 的 checkpoint_prepare() / checkpoint_restore(),并为不支持的后端发出 logger.warning_once。
- 实现 FlashInfer 资源管理:在
flashinfer_all_reduce.py 中新增模块级字典 _fi_ar_workspace_groups 追踪工作空间所属的 process group;新增 _fi_ar_workspaces_for_group(group) 筛选属于给定 group 的工作空间列表;新增 checkpoint_prepare_fi_ar_workspaces() / checkpoint_restore_fi_ar_workspaces() 对每个工作空间调用对应方法,其中 restore 会创建新的 TorchDistBackend。
- 串联分布式状态:在
parallel_state.py 中新增 _apply_to_device_comms(action) 遍历所有注册 group 的 device communicator 并执行操作;新增 checkpoint_prepare_distributed_state() / checkpoint_restore_distributed_state() 在 acceleration 同步前后对每个 communicator 调用钩子。
- CudaCommunicator 具体实现:覆写
checkpoint_prepare / checkpoint_restore,依次处理 FlashInfer all-reduce 工作空间和 all-to-all 管理器。
- All2All 管理器支持:在
all2all.py 的 NVLink MoE all-to-all 管理器(MNNVLAll2AllManager)中添加 checkpoint_prepare / checkpoint_restore,restore 时使用新的 CustomCommunicator。
- 顶层入口:在
async_llm.py 和 gpu_worker.py 中添加 checkpoint_prepare / checkpoint_restore 方法,通过 collective_rpc 在 worker 间同步触发。
- 融合算子适配:将
allreduce_rms_fusion.py 和 fused_allreduce_gemma_rms_norm.py 中创建 FlashInfer 工作空间的 group 参数从 device_group 改为 cpu_group,使得 restore 不依赖 NCCL(NCCL 可能不可用)。
- 测试覆盖:在
tests/distributed/test_comm_ops.py 中新增 test_cuda_communicator_checkpoints_flashinfer_workspaces,但该测试仅验证 lint,未包含 GPU runtime 执行。
关键文件:
vllm/distributed/device_communicators/flashinfer_all_reduce.py(模块 分布式通信;类别 source;类型 dependency-wiring;符号 _fi_ar_workspaces_for_group, checkpoint_prepare_fi_ar_workspaces, checkpoint_restore_fi_ar_workspaces): 核心 FlashInfer 工作空间管理,新增 workspace-group 映射和 prepare/restore 函数,是 propose 生命周期的直接实现。
vllm/distributed/parallel_state.py(模块 分布式通信;类别 source;类型 core-logic;符号 _apply_to_device_comms, checkpoint_prepare_distributed_state, checkpoint_restore_distributed_state): 新增 _apply_to_device_comms 遍历所有 device communicator,以及全局 checkpoint_prepare_distributed_state/checkpoint_restore_distributed_state 作为顶层调度入口。
vllm/distributed/device_communicators/base_device_communicator.py(模块 分布式通信;类别 source;类型 core-logic;符号 checkpoint_prepare, checkpoint_restore): 定义基类 no-op 钩子,提供默认实现并记录 warning,是生命周期的契约定义点。
vllm/distributed/device_communicators/cuda_communicator.py(模块 分布式通信;类别 source;类型 core-logic;符号 checkpoint_prepare, checkpoint_restore): CudaCommunicator 实现 checkpoint 钩子,路由到 FlashInfer all-reduce 和 all-to-all 管理器,是核心执行者。
vllm/distributed/device_communicators/all2all.py(模块 分布式通信;类别 source;类型 core-logic;符号 checkpoint_prepare, checkpoint_restore): All2AllManager 支持 checkpoint,特别是 MNNVLAll2AllManager 中对 NVLink MoE 工作空间的管理。
vllm/v1/engine/async_llm.py(模块 引擎;类别 source;类型 core-logic;符号 checkpoint_prepare, checkpoint_restore): 提供顶层 checkpoint 入口,通过 collective_rpc 广播到所有 worker。
vllm/v1/worker/gpu_worker.py(模块 Worker;类别 source;类型 core-logic;符号 checkpoint_prepare, checkpoint_restore): GPUWorker 响应 checkpoint 指令,调用 distributed_state 层的全局函数。
tests/distributed/test_comm_ops.py(模块 通信测试;类别 test;类型 test-coverage;符号 test_cuda_communicator_checkpoints_flashinfer_workspaces): 新增关于 FlashInfer workspace checkpoint 的单元测试骨架,验证基本调用链路,但未执行 GPU runtime。
关键符号:checkpoint_prepare_distributed_state, checkpoint_restore_distributed_state, _apply_to_device_comms, _fi_ar_workspaces_for_group, checkpoint_prepare_fi_ar_workspaces, checkpoint_restore_fi_ar_workspaces, CudaCommunicator.checkpoint_prepare, CudaCommunicator.checkpoint_restore, MNNVLAll2AllManager.checkpoint_prepare, MNNVLAll2AllManager.checkpoint_restore, test_cuda_communicator_checkpoints_flashinfer_workspaces
关键源码片段
vllm/distributed/device_communicators/flashinfer_all_reduce.py
核心 FlashInfer 工作空间管理,新增 workspace-group 映射和 prepare/restore 函数,是 propose 生命周期的直接实现。
# flashinfer_all_reduce.py 关键新增片段
from typing import Any
# ... 现有全局变量 ...
_fi_ar_workspace_groups: dict[int, ProcessGroup] = {} # workspace id -> group
def _create_workspace(...):
# ... 原有 workspace 创建逻辑 ...
# 在创建成功后记录 workspace 与 group 的关联
workspace_id = id(workspace)
workspace_group = _fi_ar_workspace_groups.get(workspace_id)
if workspace_group is not None and workspace_group is not group:
raise RuntimeError(
"FlashInfer returned an all-reduce workspace already associated "
"with a different process group"
)
_fi_ar_workspace_groups[workspace_id] = group
return workspace
def _fi_ar_workspaces_for_group(group: ProcessGroup) -> list[Any]:
"""返回属于给定 `group` 的 FlashInfer workspace 列表(按 identity 去重)"""
workspaces = [_fi_ar_workspace]
if _fi_ar_quant_workspace is not _fi_ar_workspace:
workspaces.append(_fi_ar_quant_workspace)
group_workspaces = []
for workspace in workspaces:
if workspace is None:
continue
workspace_group = _fi_ar_workspace_groups.get(id(workspace))
if workspace_group is None:
raise RuntimeError("FlashInfer all-reduce workspace process group was not retained")
if workspace_group is group:
group_workspaces.append(workspace)
return group_workspaces
def checkpoint_prepare_fi_ar_workspaces(group: ProcessGroup) -> None:
"""释放 FlashInfer 外部资源,使进程可以安全 checkpoint"""
for workspace in _fi_ar_workspaces_for_group(group):
workspace.checkpoint_prepare()
def checkpoint_restore_fi_ar_workspaces(group: ProcessGroup) -> None:
"""从 checkpoint 恢复 FlashInfer 外部资源,使用新 `TorchDistBackend`"""
for workspace in _fi_ar_workspaces_for_group(group):
workspace.checkpoint_restore(TorchDistBackend(group=group))
评论区精华
- 融合算子 checkpoint 支持:reviewer tlrmchlsmth 询问 fused allreduce 算子是否也支持 checkpoint,作者 galletas1712 答复已通过添加 fused ops 支持解决(PR 后续变更覆盖了 AllReduce-RMSNorm 和 FusedAllReduceGemmaRMSNorm)。
- group 选择(cpu_group vs device_group):tlrmchlsmth 发现
allreduce_rms_fusion.py 中将 group 从 device_group 改为 cpu_group,质疑动机。galletas1712 解释:restore 应该不依赖 NCCL(NCCL 可能已被 checkpoint 破坏),而 GLOO 的 TCP socket 迁移在 CRIU 下更可靠。tlrmchlsmth 表示理解并确认。
- 调用序列与顶层集成:评论者 matteso1 在 issue 中询问 checkpoint_prepare/restore 与 sleep/wake_up 的配合顺序,galletas1712 说明序列为
checkpoint_prepare -> sleep -> (checkpoint/restore) -> wake_up -> checkpoint_restore,并补充添加了 AsyncLLM 的顶层方法以确保顺序正确。
- 融合算子 checkpoint 支持确认 (design): 已确认融合算子 checkpoint 在后续变更中覆盖。
- group 从 device_group 改为 cpu_group 的原因 (design): 设计决定:checkpoint restore 使用 cpu_group 以避免对 NCCL 的依赖。
- checkpoint 钩子的调用序列与顶层集成 (correctness): 调用序列明确,PP group 暂未纳入当前实现但已有计划。
风险与影响
- 风险:
- 依赖 FlashInfer API 稳定性:使用 FlashInfer 0.6.15.post1 提供的 workspace checkpoint API,后续上游变更可能破坏兼容性。
- 融合算子 group 变更:将 allreduce_rms_fusion.py 等中的 group 从 device_group 改为 cpu_group 可能影响非 checkpoint 场景下的性能或正确性(例如 CUDA graph capture 中使用 gloo 可能回退)。但作者论证 CPU group 在 checkpoint 场景下更可靠,正常路径不受影响。
- 缺少 GPU runtime 测试:新增的测试
test_cuda_communicator_checkpoints_flashinfer_workspaces 仅运行预提交 lint,未执行实际的 GPU 多卡 checkpoint 验证,潜在回归风险。
- 未覆盖的通信后端:其他 device communicator(如 NCCL、custom-all-reduce)使用默认 no-op 实现,在 checkpoint 时可能不会释放资源,导致 checkpoint 状态不一致。
- 同步开销:每次 checkpoint_prepare/restore 都会调用
torch.accelerator.synchronize(),在大型模型上可能增加 checkpoint 延迟。
- 影响:影响集中在 vllm/distributed/ 模块和 vllm/v1/engine 相关文件的扩展。对用户透明:不改变模型执行路径、API、或性能特征,除非主动通过 checkpoint 工具触发。影响程度中等:新增的钩子函数在其他通信后端(如 NCCLCheckpoint)中也可复用,但当前仅在 FlashInfer 上实现。对系统影响:使得 vLLM 可以被 CRIU 等工具进程级 checkpoint,有利于长时间运行服务的弹性恢复。
- 风险标记:依赖 FlashInfer API, 融合 op 组变更, 缺少 GPU runtime 测试, 分布式进程同步
关联脉络
- PR #46234 Release communicator memory during ordinary sleep using suspend/resume: 该 PR 在 sleep 期间释放通信器内存;当前 PR 的 checkpoint 钩子是独立生命周期,不与之冲突。
- PR #47500 Explore broader backend lifecycle orchestration: 该 PR 探索更广泛的后端生命周期编排;当前 PR 仅实现 FlashInfer 资源钩子供其调用。
- PR #47806 Concerns vLLM custom-all-reduce IPC suspend/resume: 该 PR 关注 vLLM 自定义 all-reduce 的 IPC 挂起/恢复;当前 PR 处理 FlashInfer 而非 custom-all-reduce。
参与讨论