ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

大模型部署从0到1(四):多机多卡 vLLM+Ray 分布式张量并行部署Qwen3.5-122B-A10B-FP8实战

大模型部署从0到1(四):多机多卡 vLLM+Ray 分布式张量并行部署Qwen3.5-122B-A10B-FP8实战 1. 多机多卡部署 Qwen3.5-122B-A10B-FP8 的真实痛点单机四卡跑 122B 级模型很多人第一次尝试都会卡在显存上。Qwen3.5-122B-A10B-FP8 即使做了 FP8 量化权重体积仍有约 62GB单台 4×32GB 的机器做 TP4权重就吃掉 15.5GB/卡留给 KV cache 的空间非常紧张。一旦你想开 256K 长上下文或者把并发拉到 16 以上OOM 几乎是必然的。多机多卡分布式张量并行Tensor Parallelism就是解决这个问题的路径把模型权重按张量维度切分到两台甚至更多机器的所有 GPU 上让 8 张卡共同承载一个模型实例。这样单卡权重降到约 7.75GB剩余显存可以大方地分给 KV cache 和并发请求。但多机部署的复杂度不在 vLLM 本身而在三件事Ray 集群能不能正确组网、NCCL 通信有没有走对网卡、两台机器的环境是否完全一致。我见过太多案例vLLM 参数写得没问题结果卡在 NCCL 超时或者 Ray 节点注册到管理网卡上排查半天。这篇是「大模型部署从0到1」系列的第四篇聚焦二机八卡2×4×RTX 5090D 32GB用 vLLM Ray 部署 Qwen3.5-122B-A10B-FP8 的完整流程。适合已经完成单机多卡部署、想进一步突破单节点显存上限的读者。下面从 Ray 集群启动、NCCL 环境变量、vLLM 张量并行参数到吞吐验证一步步给可复制的命令。2. TaoToken 前置准备与 Ray 集群环境搭建在正式启动分布式推理之前先把集群编排和模型文件这两块基础打牢。Ray 负责跨节点调度 GPU 资源vLLM 通过 Ray 后端把张量并行任务分发到所有 worker 上。如果 Ray 集群本身不稳定后面 vLLM 启动必然失败。2.1 硬件拓扑与节点角色以下为通用示例配置可根据自身硬件规格灵活调整卡数与型号节点角色GPU 规格单卡显存单节点 GPU 数单节点总显存节点示例 IPHead 主节点RTX 5090D32GB4128GB192.168.1.10Worker 工作节点RTX 5090D32GB4128GB192.168.1.11集群总计----8256GBTP8 全量分布式按 0.85 显存利用率估算整体有效显存约 32GB × 8 × 0.85 ≈ 218GB可稳定承载 122B FP8 量化模型加 256K 上下文推理。2.2 基础环境要求两台服务器均需完成以下环境配置可参考系列第一篇组件版本要求验证命令NVIDIA 驱动 570nvidia-smiDocker 24.0docker --versionDocker Compose 2.0docker compose versionNVIDIA Container Toolkit 1.14nvidia-ctk --version2.3 模型文件准备两台服务器必须各存放一份完全一致的模型文件且分片数量、文件大小完全相同。推荐两种获取方式。同节点分别下载通过 ModelScope 或 HF 镜像站分别下载到两台服务器# 示例HF 镜像站下载 export HF_ENDPOINThttps://hf-mirror.com huggingface-cli download Qwen/Qwen3.5-122B-A10B-FP8 --local-dir /data/models/Qwen3.5-122B-A10B-FP8 # 示例ModelScope CLI 下载国内推荐速度稳定 modelscope download --model Qwen/Qwen3.5-122B-A10B-FP8 --local_dir /data/models/Qwen3.5-122B-A10B-FP8单节点下载加 rsync 同步推荐一台下载完成后内网同步到另一台节省带宽且保证文件一致# 在 Worker 节点执行从 Head 同步模型 rsync -avP --progress root192.168.1.10:/data/models/Qwen3.5-122B-A10B-FP8/ \ /data/models/Qwen3.5-122B-A10B-FP8/2.4 防火墙与端口要求跨节点通信需要开放以下端口内网环境建议直接放行整个子网端口用途方向6379Ray GCS 全局控制服务Head 监听Worker → Head8000vLLM API 服务Head 监听客户端 → Head10001-10999Ray 内部进程通信双向动态端口NCCLGPU 跨节点通信双向# 内网环境最简方案放行子网 sudo ufw allow from 192.168.1.0/242.5 网络关键要求跨节点张量并行对网络质量极其敏感。推荐使用 10Gbps 及以上专用高速网卡优先走 RoCE 网络节点间 ping 延迟必须小于 1ms零丢包NCCL 通信必须指定高速网卡禁止走管理网卡否则会出现通信超时、推理速度骤降。2.6 高速网卡配置核心踩坑点建议两台服务器的高速网卡名称尽量保持一致。网卡名统一可以大幅降低 NCCL 通信参数的配置与排错成本避免因两边网卡名不匹配导致 NCCL 走错网卡、通信超时、推理速度异常等问题。若不同节点网卡名称不同需确保后续配置中 NCCL_SOCKET_IFNAME 分别填写对应节点的真实高速网卡名不可直接复制复用同一配置。很多分布式部署失败根源是 NCCL 走了错误的网卡。如果你的高速网卡被配置在网桥下必须先移出网桥直接绑定 IP。# 1. 从网桥中移出网卡 ip link set highspeed0 nomaster # 2. 关闭并删除旧网桥 ip link set br0 down 2/dev/null ip link delete br0 2/dev/null # 3. 直接给网卡配置 IP ip addr add 192.168.1.11/24 dev highspeed0 # 4. 验证配置 ip addr show highspeed0注意以上为临时配置重启后失效。持久化配置可通过 netplan 完成。3. Head 主节点与 Worker 节点可复制配置这一节给出两台机器上可直接复制的启动脚本和 docker-compose 配置。Head 节点负责 Ray 集群管控、vLLM 服务启动与 API 对外暴露Worker 节点仅提供 GPU 算力不对外暴露 API。3.1 Head 节点 Ray 启动脚本在模型目录下创建 start_head.shmkdir -p /data/models/Qwen3.5-122B-A10B-FP8 cat /data/models/Qwen3.5-122B-A10B-FP8/start_head.sh EOF #!/bin/bash set -e # 安装 Ray 及依赖 pip install -U ray[default] sentencepiece tiktoken # 启动 Ray Head 节点 ray start --head \ --node-ip-address192.168.1.10 \ --port6379 \ --num-gpus4 \ --object-store-memory 17179869184 \ --disable-usage-stats # 保持容器运行 sleep infinity EOF chmod x /data/models/Qwen3.5-122B-A10B-FP8/start_head.sh3.2 Head 节点 docker-compose.ymlservices: vllm-head: image: vllm/vllm-openai:v0.20.1 container_name: vllm-head restart: unless-stopped shm_size: 32G network_mode: host deploy: resources: reservations: devices: - driver: nvidia count: 4 capabilities: [gpu] volumes: - /data/models/Qwen3.5-122B-A10B-FP8:/app/models/Qwen3.5-122B-A10B-FP8 - /data/models/cache:/root/.cache/huggingface - /data/models/logs:/app/logs - ./start_head.sh:/start.sh:ro environment: - TZAsia/Shanghai - VLLM_HOST_IP192.168.1.10 - NCCL_SOCKET_IFNAMEhighspeed0 - NCCL_IB_DISABLE1 - HF_ENDPOINThttps://hf-mirror.com entrypoint: [/bin/bash, /start.sh]关键说明network_mode: host 使用宿主机网络减少 NAT 转发损耗是分布式部署的必要配置NCCL_SOCKET_IFNAME 强制 NCCL 走高速网卡是跨节点通信正常的核心参数shm_size 设置大共享内存满足多卡 NCCL 通信需求。3.3 Worker 节点 Ray 启动脚本mkdir -p /data/models/Qwen3.5-122B-A10B-FP8 cat /data/models/Qwen3.5-122B-A10B-FP8/start_worker.sh EOF #!/bin/bash set -e # 安装 Ray 及依赖与 Head 版本保持一致 pip install -U ray[default] sentencepiece tiktoken # 加入 Ray 集群 ray start --address192.168.1.10:6379 \ --node-ip-address192.168.1.11 \ --num-gpus4 \ --object-store-memory 17179869184 \ --disable-usage-stats \ --block EOF chmod x /data/models/Qwen3.5-122B-A10B-FP8/start_worker.sh3.4 Worker 节点 docker-compose.ymlservices: vllm-worker: image: vllm/vllm-openai:v0.20.1 container_name: vllm-worker restart: unless-stopped shm_size: 32G network_mode: host deploy: resources: reservations: devices: - driver: nvidia count: 4 capabilities: [gpu] volumes: - /data/models/Qwen3.5-122B-A10B-FP8:/app/models/Qwen3.5-122B-A10B-FP8 - /data/models/cache:/root/.cache/huggingface - /data/models/logs:/app/logs - ./start_worker.sh:/start_worker.sh:ro environment: - TZAsia/Shanghai - VLLM_HOST_IP192.168.1.11 - NCCL_SOCKET_IFNAMEhighspeed0 - NCCL_IB_DISABLE1 - HF_ENDPOINThttps://hf-mirror.com entrypoint: [/bin/bash, /start_worker.sh]3.5 启动顺序先启动 Head再启动 Worker# Head 节点 cd /data/models/Qwen3.5-122B-A10B-FP8 docker compose down docker compose up -d # Worker 节点等 Head 起来后执行 cd /data/models/Qwen3.5-122B-A10B-FP8 docker compose down docker compose up -d4. 验证请求与成功结果Ray 集群状态与 vLLM 推理测试配置写完后必须逐层验证先确认 Ray 集群识别到 8 张 GPU再确认 vLLM 服务正常启动最后用 curl 验证推理接口。4.1 Ray 集群状态校验两节点启动后等待约 30 秒在 Head 节点容器内执行集群状态校验docker exec vllm-head python3 -c import ray ray.init(addressauto) for node in ray.nodes(): print(f\IP: {node.get(NodeManagerAddress)} Alive: {node[Alive]} GPUs: {node.get(Resources,{}).get(GPU,0)}\) 预期输出IP: 192.168.1.10 Alive: True GPUs: 4.0 IP: 192.168.1.11 Alive: True GPUs: 4.0如果 Worker 显示的 IP 是管理网卡地址说明 --node-ip-address 未生效检查启动脚本并重启 Worker。4.2 启动 vLLM 分布式推理服务进入 Head 容器内执行启动命令# 进入 Head 容器 docker exec -it vllm-head /bin/bash # 启动 vLLM 分布式服务 nohup python3 -m vllm.entrypoints.openai.api_server \ --model /app/models/Qwen3.5-122B-A10B-FP8 \ --served-model-name Qwen3.5-122B-A10B-FP8 \ --tensor-parallel-size 8 \ --host 192.168.1.10 \ --port 8000 \ --trust-remote-code \ --max-model-len 262144 \ --max-num-seqs 8 \ --gpu-memory-utilization 0.85 \ --kv-cache-dtype fp8 \ --distributed-executor-backend ray \ --enable-auto-tool-choice \ --tool-call-parser qwen3_coder \ --reasoning-parser qwen3 \ --language-model-only \ --speculative-config {method:mtp,num_speculative_tokens:2} \ /tmp/vllm.log 21 # 实时查看启动日志 tail -f /tmp/vllm.log核心参数说明参数作用推荐值--tensor-parallel-size张量并行度等于总 GPU 数量8--distributed-executor-backend ray指定分布式后端为 Ray固定值 ray--max-model-len最大上下文长度262144256K--max-num-seqs最大并发请求数8--kv-cache-dtype fp8KV cache 采用 FP8 存储节约约 50% 显存--language-model-only纯文本模式跳过视觉编码器节省显存--speculative-configMTP 多 Token 投机解码吞吐提升 1.5-2 倍日志中出现 INFO: Starting vLLM server on http://192.168.1.10:8000 即代表服务启动完成。122B 模型加载约需 3-5 分钟依次完成权重加载、NCCL 通信初始化、KV cache 分配、API 服务启动四个阶段。4.3 服务接口验证服务就绪后可通过 curl 进行全功能验证# 查看模型列表 curl http://192.168.1.10:8000/v1/models # 基础对话测试 curl http://192.168.1.10:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: Qwen3.5-122B-A10B-FP8, messages: [{role: user, content: 你好请用一句话介绍你自己}], max_tokens: 200, temperature: 0.7 } # 流式输出测试 curl http://192.168.1.10:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: Qwen3.5-122B-A10B-FP8, messages: [{role: user, content: 写一首关于AI的五言绝句}], stream: true }4.4 吞吐与显存占用验证服务跑起来后用 vLLM 自带的 benchmark 脚本压测观察实际吞吐# 在 Head 容器内执行 python3 -m vllm.entrypoints.openai.api_server --help /dev/null # 使用 benchmark_serving 压测 python3 -m vllm.benchmarks.benchmark_serving \ --backend openai-chat \ --base-url http://192.168.1.10:8000 \ --model Qwen3.5-122B-A10B-FP8 \ --dataset-name random \ --num-prompts 100 \ --request-rate 8同时另开终端观察两节点显存# 两节点分别执行 nvidia-smi --query-gpuindex,memory.used,memory.total,utilization.gpu --formatcsvTP8 配置下单卡权重约 7.75GBKV cache 按 256K 上下文和并发 8 估算约 15GB单卡总占用约 23-25GB32GB 显存留有安全余量。5. 本篇常见错误排查401、local proxy failed、reading choices、OAuth分布式部署的报错往往不在 vLLM 参数本身而在网络和认证层。下面按真实报错逐条对照。5.1 401 Unauthorized如果你在 vLLM 前面挂了网关或反向代理客户端请求可能返回 401。检查两点一是 vLLM 本身是否设置了 --api-key如果设置了客户端请求头必须带 Authorization: Bearer 二是如果通过 TaoToken 这类统一网关转发确认网关侧的 Key 与 vLLM 侧配置一致。# 带 Key 的请求示例 curl http://192.168.1.10:8000/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer your-api-key \ -d {model:Qwen3.5-122B-A10B-FP8,messages:[{role:user,content:hi}]}5.2 local proxy failed这个报错通常出现在 Ray worker 无法连接 Head 的 GCS 服务时。排查顺序先确认 Head 的 6379 端口在监听再确认 Worker 能 ping 通 Head 的高速网卡 IP最后检查防火墙是否放行了 10001-10999 动态端口段。# Head 节点确认端口监听 ss -tlnp | grep 6379 # Worker 节点测试连通性 nc -zv 192.168.1.10 63795.3 reading choices 报错这个报错一般出现在客户端解析流式响应时服务端返回的不是标准 SSE 格式。常见原因是 vLLM 版本与客户端 SDK 不匹配或者中间代理对 chunked 响应做了缓冲。解决方式是直接用 curl 测试原始响应确认服务端输出正常再排查代理层。# 直接看原始流式响应 curl -N http://192.168.1.10:8000/v1/chat/completions \ -H Content-Type: application/json \ -d {model:Qwen3.5-122B-A10B-FP8,messages:[{role:user,content:hi}],stream:true}5.4 OAuth 相关报错如果你用 Claude Code 或 Codex 这类工具接入自建推理服务可能会遇到 OAuth 认证失败。这类工具默认走官方端点需要手动改配置指向你的 vLLM 服务。以 Claude Code 为例需要设置 ANTHROPIC_BASE_URL 和 ANTHROPIC_API_KEY 两个环境变量Base URL 填你的 vLLM 地址Key 填 vLLM 的 api-key。如果你用的是 CC Switch 或 Cline MCP 这类工具配置里必须写全三件套Base URL、Key、Model ID。缺任何一个都会导致认证或模型找不到的报错。{ baseUrl: http://192.168.1.10:8000/v1, apiKey: your-api-key, model: Qwen3.5-122B-A10B-FP8 }5.5 NCCL 通信超时这是分布式部署最高频的报错。排查清单NCCL_SOCKET_IFNAME 两节点是否一致且指向高速网卡高速网卡是否互通ping 延迟是否小于 1ms防火墙是否放行网卡带宽是否达到 10Gbps 以上。带宽不足会严重拖慢推理速度。5.6 显存不足 OOM先清理两节点残留 GPU 进程与容器再降低 --max-num-seqs 或 --max-model-len适当调低 --gpu-memory-utilization。# 查看残留进程 nvidia-smi # 清理 Ray 残留 docker exec vllm-head rm -rf /tmp/ray docker exec vllm-worker rm -rf /tmp/ray6. 长期编码与 Agent 场景的接入建议分布式推理服务跑起来后真正的价值在于把它接入日常开发流。如果你主要做长上下文编码、Agent 编排这类任务建议把 vLLM 服务作为统一后端前端用支持自定义 Base URL 的客户端接入。对于需要长期稳定运行的编码场景可以考虑用 Coding Plan 这类方案做统一调度把多台机器的推理能力池化按任务类型分流。模型对话类需求可以直接走模型对话入口验证效果接入文档里有完整的 Base URL 和 Key 配置说明。实际接入时Base URL 填你的 vLLM 服务地址加 /v1Key 填 vLLM 启动时设置的 api-keyModel ID 填 --served-model-name 指定的名称。这三件套在 CC Switch、Cline MCP、Codex 的 auth.json 里都是必填项缺一不可。{ provider: openai-compatible, baseUrl: http://192.168.1.10:8000/v1, apiKey: your-api-key, model: Qwen3.5-122B-A10B-FP8 }日常运维常用命令# 查看 Ray 集群状态 docker exec vllm-head ray status # 查看 vLLM 运行日志 docker exec vllm-head tail -f /tmp/vllm.log # 重启 vLLM 服务不重启容器 docker exec vllm-head pkill -f vllm.entrypoints # 完整重启集群 # Head 节点docker compose down docker compose up -d # Worker 节点docker compose down docker compose up -d踩过的坑里最值得记住的一条是分布式部署的成败八成取决于网络配置而不是 vLLM 参数。网卡配对、NCCL 走对接口、两节点环境一致这三点做到位剩下的就是等模型加载。
返回列表