☰
vLLM 部署实战:从单卡到多卡的高性能推理服务配置与验证
2026/9/29 4:39:37 网站建设 项目流程

1. 为什么单卡跑得好好的,一上多卡就翻车

vLLM 是一个面向大模型推理的高吞吐服务框架,核心能力是把 PagedAttention、Continuous Batching、Prefix Caching 这些优化默认打开,对外暴露一套 OpenAI 兼容 API。它适合谁?适合手里有 1 到 8 张 GPU、想把本地模型变成稳定 HTTP 服务、又不想自己写调度逻辑的工程师。单卡部署通常一条vllm serve就能跑通,但真正让人头疼的是从单卡切到多卡的那一刻:启动参数变了、显存分配逻辑变了、并行策略选错直接 OOM 或者吞吐不升反降。

我见过太多人卡在这一步:单卡 7B 跑得飞起,换成 4 卡 32B 就报CUDA out of memory,或者服务起来了但 TTFT(首 token 延迟)从 200ms 飙到 5s。问题往往不在模型本身,而在--tensor-parallel-size、--gpu-memory-utilization、--max-num-seqs这几个参数的组合上。这篇就按“单卡起步 → 多卡并行 → 压测验证”的顺序,把可复制的配置和排障动作一次讲清,同时给出用 TaoToken 统一 Key 接入的示例,方便你在多环境之间切换时不用反复改客户端代码。

2. 前置准备:环境、模型与 TaoToken 通道

2.1 硬件与软件基线

先确认你的卡能不能装下模型。经验值如下,FP16 权重按参数量 ×2 字节估算,再留 20% 给 KV Cache:

模型规模推理显存推荐卡型
7B FP16约 16GBA10 24GB / 4090 24GB
7B INT4约 6GB任意 12GB+
14B FP16约 30GBA100 40GB / L40 48GB
32B INT4约 20GB4090 24GB(紧张)
70B INT4约 40GBA100 80GB / H100 80GB
70B FP16约 150GB2×H100 80GB

软件侧建议 CUDA 12.x + Python 3.10,用 conda 隔离环境:

conda create -n vllm python=3.10 -y conda activate vllm pip install vllm==0.6.4 python -c "import vllm; print(vllm.__version__)"

2.2 TaoToken 统一 Key 与 API 通道

多卡部署时经常要在本地服务、云端服务、不同机器之间切换,如果每个环境都维护一套 Key 会很乱。TaoToken 提供统一的 Key 和 API 通道,把模型对话、Coding Plan、控制台、API Keys 管理都收在一个入口。你可以在控制台创建 Key,然后在客户端里把base_url指向统一通道,本地 vLLM 和远端服务用同一套调用代码。

  • 官网入口:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
  • API 地址:https://taotoken.net/api
  • 模型对话:https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite
  • Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite
  • 控制台:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite
  • API Keys:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite
  • 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite

注意:TaoToken 是统一接入通道,不是替代 vLLM 的推理引擎。vLLM 负责本地 GPU 上的模型推理,TaoToken 负责 Key 管理和多环境调用统一。

3. 可复制配置:从单卡到多卡的启动骨架

3.1 单卡最小可用启动

先跑通单卡,确认模型能加载、API 能响应:

vllm serve Qwen/Qwen3-7B-Instruct \ --served-model-name qwen3-7b \ --dtype bfloat16 \ --max-model-len 8192 \ --gpu-memory-utilization 0.90 \ --port 8000

这条命令会自动从 HuggingFace 拉模型、启动 OpenAI 兼容 API(默认 8000 端口)、打开 PagedAttention 和 Continuous Batching。验证一下:

curl http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "qwen3-7b", "messages": [{"role": "user", "content": "你好"}] }'

返回里能看到choices[0].message.content就说明单卡通了。

3.2 多卡并行:TP 与 PP 怎么选

多卡的核心是并行策略。三种方式的分工:

并行方式切分对象适用场景通信开销
Tensor Parallel (TP)单层算子单机多卡高,需 NVLink
Pipeline Parallel (PP)模型层多机部署中,跨机
Data Parallel (DP)不同请求高并发吞吐低,独立副本

规则很简单:TP 用来“装下”模型,DP 用来“扩大”并发,PP 用来“跨机”。单机 4 卡部署 32B 模型,用 TP=4:

vllm serve Qwen/Qwen3-32B-Instruct \ --served-model-name qwen3-32b \ --tensor-parallel-size 4 \ --pipeline-parallel-size 1 \ --dtype bfloat16 \ --quantization fp8 \ --kv-cache-dtype fp8 \ --max-model-len 32768 \ --enable-prefix-caching \ --enable-chunked-prefill \ --max-num-batched-tokens 16384 \ --max-num-seqs 256 \ --gpu-memory-utilization 0.92 \ --swap-space 16 \ --host 0.0.0.0 \ --port 8000 \ --api-key sk-your-secret-key

TP 数必须是模型 attention heads 数的因子。比如 64 heads,TP 可以是 1/2/4/8/16。跨机才用 PP,比如 2 机 × 8 卡部署 405B:

# Master 节点 vllm serve meta-llama/Llama-3-405B-Instruct \ --tensor-parallel-size 8 \ --pipeline-parallel-size 2 \ --distributed-executor-backend ray \ --num-nodes 2 \ --node-rank 0

3.3 config.toml 骨架

如果你用配置文件管理参数,可以按这个骨架组织,方便单卡/多卡切换时只改并行段:

[model] name = "Qwen/Qwen3-32B-Instruct" served_name = "qwen3-32b" dtype = "bfloat16" max_model_len = 32768 [quantization] method = "fp8" kv_cache_dtype = "fp8" [parallel] tensor_parallel_size = 4 pipeline_parallel_size = 1 [optimization] enable_prefix_caching = true enable_chunked_prefill = true max_num_batched_tokens = 16384 max_num_seqs = 256 [memory] gpu_memory_utilization = 0.92 swap_space = 16 [server] host = "0.0.0.0" port = 8000 api_key = "sk-your-secret-key"

单卡时把tensor_parallel_size改成 1、去掉quantization段即可,其余不动。

4. 验证请求与成功结果

4.1 健康检查与模型列表

服务起来后先做三步验证:

# 1. 健康检查 curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/health # 期望输出 200 # 2. 模型列表 curl http://localhost:8000/v1/models \ -H "Authorization: Bearer sk-your-secret-key" # 3. 实际推理 curl http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sk-your-secret-key" \ -d '{"model":"qwen3-32b","messages":[{"role":"user","content":"hi"}]}'

4.2 用 TaoToken 通道调用

把客户端base_url指向 TaoToken 统一通道,Key 用控制台创建的:

from openai import OpenAI client = OpenAI( base_url="https://taotoken.net/api", api_key="sk-your-taotoken-key" ) resp = client.chat.completions.create( model="qwen3-32b", messages=[{"role": "user", "content": "解释一下 KV Cache"}], stream=True ) for chunk in resp: print(chunk.choices[0].delta.content or "", end="", flush=True)

这样本地 vLLM 和远端服务用同一套调用代码,切换环境只改base_url。

4.3 压测验证单卡/多卡切换

切换并行配置后必须压测,否则你不知道吞吐有没有真的提升。用 vLLM 自带的 benchmark:

# 安装压测工具 pip install vllm[benchmark] # 单卡基线 python -m vllm.entrypoints.benchmark.benchmark_serving \ --backend openai \ --base-url http://localhost:8000 \ --model qwen3-32b \ --dataset-name sharegpt \ --num-prompts 200 \ --request-rate 10 # 多卡切换后重跑,对比 TTFT 和吞吐

关注三个指标:TTFT p99、TPOT(每 token 延迟)p99、requests/s。多卡 TP 后吞吐应该接近线性提升,如果没提升,多半是 TP 通信成了瓶颈,检查有没有 NVLink。

5. 本篇常见错排查

5.1 启动 OOM

症状:CUDA out of memory。按优先级排查:

# 先关 cuda graph 看真实占用 vllm serve ... --enforce-eager

对策顺序:降--gpu-memory-utilization到 0.85 → 降--max-num-seqs→ 开--kv-cache-dtype fp8→ 开--quantization fp8→ 降--max-model-len→ 加 TP。

5.2 TTFT 飙高

症状:TTFT 从 200ms 跳到 5s+。原因是长 prompt 阻塞了短请求。开 chunked prefill:

--enable-chunked-prefill --max-num-batched-tokens 8192

5.3 流式输出中断

症状:客户端流式输出中途断开。多半是 nginx 或 ingress 的 buffering 和 timeout:

proxy_buffering off; proxy_read_timeout 600s; proxy_send_timeout 600s;

5.4 多卡吞吐不升反降

症状:TP=4 后吞吐比单卡还低。检查 TP 数是否是 attention heads 的因子,检查卡间是否有 NVLink。跨机 TP 通信开销大,应该改用 PP。

5.5 模型加载慢

70B 模型每次启动 5-10 分钟。对策:模型放本地 SSD 不要用 NFS,用 safetensors 格式,K8s 里livenessProbe的initialDelaySeconds设 300+。

6. 下一步:把服务接进你的工作流

服务跑通后,日常调用建议统一走 TaoToken 通道,Key 在控制台管理,接入文档里有完整的 SDK 示例。如果你要长期做编码或 Agent 任务,可以看 Coding Plan;只是验证模型效果,用模型对话页面就够了。

  • API Keys 管理:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite
  • 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite
  • 模型对话:https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite
  • Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite

最后留一个实操建议:每次改并行参数后,别只看服务起没起来,一定要跑一遍 benchmark_serving,把 TTFT 和吞吐记下来。我试过 TP 从 2 改到 4 但没开 prefix caching,吞吐只涨了 15%,开了之后直接翻倍。参数之间的耦合比想象中大,压测数据比直觉可靠。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询