执行摘要
- 一句话:引入 DP Supervisor 支持节点级多端口外部健康聚合
- 推荐动作:值得精读,尤其是 supervisor 的进程模型、信号转发和健康聚合方式。团队可在 K8s 部署中验证默认探针参数适配性。
功能与动机
现有外部 DP 模式(--data-parallel-external-lb)启动多个独立 API 服务器,但缺乏统一健康检查和进程监督,与 Kubernetes 探针配合不佳。Issue #40814 提出需要一个节点级别 supervisor 来提供聚合健康端点并管理子进程,使部署更适应 K8s 环境。
实现拆解
-
新增配置与入口:在 cli_args.py 的 FrontendArgs 中添加 data_parallel_supervisor_port、dp_supervisor_probe_interval_s 等探测配置;在 arg_utils.py 中增加 --data-parallel-multi-port-external-lb 标志。入口 serve.py 识别该模式并调用 run_dp_supervisor(),同时与其他 LB 模式互斥。
-
参数验证与子进程构建:dp_supervisor.py 的 validate_multi_port_external_lb_args() 函数校验多端口模式的各项约束(端口重叠、size 整除、不支持 gRPC/UDS/HTTPS 等)。_build_vllm_dp_server_args() 为每个本地 rank 创建子进程参数副本,分配端口和 rank。
-
DPSupervisor 核心:run_dp_supervisor() 启动主流程:启动子进程(multiprocessing.Process),构建 FastAPI 应用并启动 uvicorn 服务器,同时设置后台任务 _monitor_children 定期探测子进程 /health 和 /readyz。收到 SIGINT/SIGTERM 后转发信号至子进程并等待退出。
-
测试覆盖:test_dp_supervisor.py 包含单元测试和生命周期集成测试。集成测试使用假的 aiohttp 服务器替代真实子进程,验证健康聚合、关闭序列和子进程崩溃等场景。
-
辅助改善:system_utils.py 的 decorate_logs 新增 skip_if_decorated 参数,避免子进程日志被重复装饰。
关键文件:
vllm/entrypoints/openai/dp_supervisor.py(模块 前端;类别 source;类型 core-logic;符号 infer_multi_port_external_lb_start_rank, validate_multi_port_external_lb_args, _build_vllm_dp_server_args, _build_vllm_dp_server_env): 核心实现文件,定义 DPSupervisor 类、参数验证、子进程管理、健康探测和管理员 FastAPI 应用。
tests/entrypoints/openai/test_dp_supervisor.py(模块 测试;类别 test;类型 test-coverage;符号 _make_unit_args, _make_args, test_infer_multi_port_external_lb_start_rank_uses_node_rank, test_build_multi_port_external_lb_child_args_sets_external_rank_server): 核心测试文件,覆盖参数推断、子进程参数构建、健康聚合、关闭事件和子进程退出等场景。
vllm/entrypoints/cli/serve.py(模块 命令行;类别 source;类型 entrypoint): 入口层修改,检测多端口模式并调用 run_dp_supervisor。
vllm/entrypoints/openai/cli_args.py(模块 前端;类别 source;类型 configuration): 添加 DP Supervisor 相关命令行参数 (data_parallel_supervisor_port, probe_interval 等) 和验证钩子。
vllm/engine/arg_utils.py(模块 引擎;类别 source;类型 configuration): 新增 --data-parallel-multi-port-external-lb 引擎参数。
vllm/utils/system_utils.py(模块 系统工具;类别 source;类型 core-logic;符号 decorate_logs): 修改 decorate_logs 支持 skip_if_decorated 参数,避免子进程日志重复装饰。
关键符号:infer_multi_port_external_lb_start_rank, validate_multi_port_external_lb_args, _build_vllm_dp_server_args, _build_vllm_dp_server_env, _child_base_url, _join_processes_with_timeout, _probe_endpoint, _build_dp_supervisor_app, decorate_logs
关键源码片段
vllm/entrypoints/openai/dp_supervisor.py
核心实现文件,定义 DPSupervisor 类、参数验证、子进程管理、健康探测和管理员 FastAPI 应用。
def validate_multi_port_external_lb_args(args: argparse.Namespace) -> None:
# 不支持 gRPC
if getattr(args, 'grpc', False):
raise ValueError(
'Error: --data-parallel-multi-port-external-lb does not support --grpc'
)
# 不支持 Unix Domain Socket
if args.uds is not None:
raise ValueError(
'Error: --data-parallel-multi-port-external-lb does not support --uds'
)
# 暂不支持 HTTPS
if any((args.ssl_keyfile, args.ssl_certfile, args.ssl_ca_certs)):
raise ValueError(
'Error: --data-parallel-multi-port-external-lb does not support HTTPS yet'
)
# 要求 api-server-count 为 1
if args.api_server_count not in (None, 1):
raise ValueError(
'Error: --data-parallel-multi-port-external-lb currently requires '
'--api-server-count=1'
)
# data-parallel-rank 由 supervisor 管理
if args.data_parallel_rank is not None:
raise ValueError(
'Error: --data-parallel-multi-port-external-lb manages child '
'--data-parallel-rank values internally'
)
# 不能与其他 LB 模式混用
if args.data_parallel_external_lb or args.data_parallel_hybrid_lb:
raise ValueError(
'Error: --data-parallel-multi-port-external-lb cannot be combined with '
'--data-parallel-external-lb or --data-parallel-hybrid-lb'
)
# data-parallel-size 必须大于 1
if args.data_parallel_size < 2:
raise ValueError(
'Error: --data-parallel-multi-port-external-lb requires '
'--data-parallel-size > 1'
)
local_size = args.data_parallel_size_local
# local size 必须 >= 2
if local_size is None or local_size < 2:
raise ValueError(
'Error: --data-parallel-multi-port-external-lb requires '
'--data-parallel-size-local >= 2'
)
# local size 不能超过全局 size
if local_size > args.data_parallel_size:
raise ValueError(
'Error: --data-parallel-size-local cannot exceed --data-parallel-size'
)
# 全局 size 必须能被 local size 整除
if args.data_parallel_size % local_size != 0:
raise ValueError(
'Error: --data-parallel-size must be divisible by '
'--data-parallel-size-local'
)
# 验证 rank 范围不越界
start_rank = infer_multi_port_external_lb_start_rank(args)
if start_rank + local_size > args.data_parallel_size:
raise ValueError(
'Error: multi-port supervised ranks would exceed --data-parallel-size'
)
# 确保 supervisor 端口不与 child 端口重叠
supervisor_port = args.data_parallel_supervisor_port
child_port_min = args.port
child_port_max = args.port + local_size - 1
if child_port_min <= supervisor_port <= child_port_max:
raise ValueError(
f'Error: --data-parallel-supervisor-port {supervisor_port} '
f'overlaps with child rank ports {child_port_min}-{child_port_max}'
)
评论区精华
风险与影响
- 风险:
- 进程管理:supervisor 负责子进程的 fork、信号转发和退出等待。若 supervisor 异常崩溃,子进程可能成为孤儿(因未设置 PDEATHSIG)。
- 健康探测:通过 HTTP 探测子进程状态,网络延迟或端口竞争可能导致误判。默认探测间隔 5s、超时 5s、失败阈值 3 可在部分场景调整。
- 兼容性:此模式默认不启用,不影响现有 DP 模式。限制不支持 gRPC、UDS、HTTPS、api-server-count>1,需在文档中说明。
- 测试覆盖:单元测试和模拟集成测试覆盖了主要逻辑,但未在真实多 GPU 集群中验证。
- 影响:对用户:提供新的 K8s 友好部署选项,简化 D-并行部署流程。对系统:增加 supervisor 进程开销。对团队:需要维护新增的 supervisor 逻辑和探针配置。
- 风险标记:进程管理复杂度, 健康探测网络依赖, PDEATHSIG 未设置, 测试覆盖真实 GPU
关联脉络
- PR #40814 [Feature]: Support a node-local external DP mode with a single vllm serve and aggregated admin health endpoint: 该 PR 是此 Feature Request 的 MVP 实现。
参与讨论