自建 vllm 服务于 vsc

自建 vllm 服务 vsc

环境准备

1
2
pip install uv 
pip install modelscope

初次尝试 Qwen3.5-27B

1
VLLM_USE_MODELSCOPE=true vllm serve Qwen/Qwen3.5-27B --port 18000 --tensor-parallel-size 4 --max-model-len 262144 --reasoning-parser qwen3

测试请求:

1
2
3
4
5
6
7
8
9
curl http://localhost:18000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen3.5-27B",
"messages": [
{"role": "user", "content": "你好,请简单介绍一下你自己。"}
],
"max_tokens": 1000
}'

OOM 问题

显存炸了,修改为 FP8 版本并优化参数:

1
VLLM_USE_MODELSCOPE=true vllm serve Qwen/Qwen3.5-27B-FP8 --port 18000 --host 0.0.0.0 --tensor-parallel-size 4 --max-model-len 262144 --gpu-memory-utilization 0.95 --reasoning-parser qwen3 --trust-remote-code

尝试 Qwen 122B 标准模型

通过 4 卡 + --cpu-offload-gb 解决内存问题:

1
SAFETENSORS_FAST_GPU=1 vllm serve MiniMax-M2.5 --trust-remote-code --tensor-parallel-size 4 --enable-auto-tool-choice --tool-call-parser minimax_m2 --reasoning-parser minimax_m2_append_think --gpu-memory-utilization 0.3 --cpu-offload-gb 150

结果:挂了

更早的无用尝试:

1
2
3
4
5
SAFETENSORS_FAST_GPU=1 vllm serve \
MiniMaxAI/MiniMax-M2.5 --trust-remote-code \
--tensor-parallel-size 4 \
--enable-auto-tool-choice --tool-call-parser minimax_m2 \
--reasoning-parser minimax_m2_append_think

2 卡尝试

1
2
3
4
5
6
CUDA_VISIBLE_DEVICES=2,3 PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True VLLM_USE_MODELSCOPE=true vllm serve Qwen/Qwen3.5-122B-A10B \
--port 8000 \
--tensor-parallel-size 2 \
--max-model-len 65536 \
--reasoning-parser qwen3 \
--gpu-memory-utilization 0.8

4 卡再试

1
VLLM_USE_MODELSCOPE=true vllm serve Qwen/Qwen3.5-122B-A10B --port 18001 --tensor-parallel-size 4 --max-model-len 65536 --reasoning-parser qwen3 --gpu-memory-utilization 0.5 --cpu-offload-gb 200

结论: 经过测试 122B 在 ollama 下也不能正确运行,加载时间 22 分钟,第二次回答报错。放弃该路径。

Qwen3.5-35B-A3B 尝试

1
VLLM_USE_MODELSCOPE=true vllm serve Qwen/Qwen3.5-35B-A3B --port 18001 --tensor-parallel-size 4 --max-model-len 262144 --reasoning-parser qwen3 --gpu-memory-utilization 0.8 --cpu-offload-gb 30

2 卡版本

1
2
3
4
5
6
CUDA_VISIBLE_DEVICES=2,3 vLLM_USE_MODELSCOPE=true vllm serve Qwen/Qwen3.5-35B-A3B \
--port 18001 \
--tensor-parallel-size 2 \ # 关键修改:由 4 改为 2
--max-model-len 262144 \
--reasoning-parser qwen3 \
--gpu-memory-utilization 0.8
1
CUDA_VISIBLE_DEVICES=2,3 vLLM_USE_MODELSCOPE=true vllm serve Qwen/Qwen3.5-35B-A3B --port 18001 --tensor-parallel-size 2 --max-model-len 262144 --reasoning-parser qwen3 --gpu-memory-utilization 0.8 --cpu-offload-gb 30

Triton 实现问题

1
VLLM_FLASH_ATTN_TRITON_IMPL=False CUDA_VISIBLE_DEVICES=2,3 vLLM_USE_MODELSCOPE=true vllm serve Qwen/Qwen3.5-35B-A3B --port 18001 --tensor-parallel-size 2 --max-model-len 262144 --reasoning-parser qwen3 --gpu-memory-utilization 0.5 --cpu-offload-gb 30

卸载出错,移除卸载过程。

4 卡版本

1
VLLM_FLASH_ATTN_TRITON_IMPL=False CUDA_VISIBLE_DEVICES=1,2,3,4 vLLM_USE_MODELSCOPE=true vllm serve Qwen/Qwen3.5-35B-A3B --port 18001 --tensor-parallel-size 4 --max-model-len 262144 --reasoning-parser qwen3 --gpu-memory-utilization 0.5 --gpu-memory-utilization 0.8

排查僵尸进程

1
ps -o pid,ppid,cmd -p 2779757

0.8B 版本成功运行

改成 0.8B 后的效果,跑起来了!

修改参数后:

1
VLLM_DISABLE_CUDA_GRAPH=True VLLM_USE_MODELSCOPE=true CUDA_VISIBLE_DEVICES=0,1,2,3 vllm serve Qwen/Qwen3.5-0.8B --port 18001 --tensor-parallel-size 4 --max-model-len 262144 --reasoning-parser qwen3 --gpu-memory-utilization 0.6 --enforce-eager

27B-FP8 最终方案

1
VLLM_DISABLE_CUDA_GRAPH=True VLLM_USE_MODELSCOPE=true CUDA_VISIBLE_DEVICES=0,1,2,3 vllm serve Qwen/Qwen3.5-27B-FP8 --port 18001 --tensor-parallel-size 4 --max-model-len 65536 --reasoning-parser qwen3 --gpu-memory-utilization 0.5 --enforce-eager

最终优化配置

增加环境变量

1
2
export VLLM_TORCH_COMPILE=1
export PYTORCH_ALLOC_CONF=expandable_segments:True

2 卡部署参数(27B-FP8)

1
2
3
4
5
6
7
8
9
10
CUDA_VISIBLE_DEVICES=1,2 vllm serve Qwen/Qwen3.5-27B-FP8 \
--port 18002 \
--tensor-parallel-size 2 \
--max-model-len 262144 \
--reasoning-parser qwen3 \
--enable-chunked-prefill \
--max-num-batched-tokens 8192 \
--gpu-memory-utilization 0.95 \
--kv-cache-dtype fp8 \
--max-num-seqs 16

2 卡部署参数(Qwen3-Coder-30B-A3B-Instruct-FP8)

1
2
3
4
5
6
7
8
9
10
11
12
13
CUDA_VISIBLE_DEVICES=0,3 VLLM_USE_MODELSCOPE=true vllm serve Qwen/Qwen3-Coder-30B-A3B-Instruct-FP8 \
--host 0.0.0.0 \
--port 18001 \
--tensor-parallel-size 2 \
--dtype auto \
--reasoning-parser qwen3 \
--enable-chunked-prefill \
--max-num-batched-tokens 8192 \
--kv-cache-dtype fp8 \
--max-num-seqs 16 \
--gpu-memory-utilization 0.8 \
--max-model-len 32768 \
--served-model-name qwen3-coder-30b-A3B-Instruct-FP8

总结

  1. 122B 模型:放弃,加载时间过长且不稳定
  2. 35B 模型:存在 Triton 实现问题,需要调整参数
  3. 27B-FP8:最终稳定方案,2 卡部署效果良好
  4. 0.8B 模型:可以快速验证,适合调试

关键优化参数:

  • --gpu-memory-utilization 0.8-0.95:根据显存大小调整
  • --enable-chunked-prefill:提升批处理性能
  • --kv-cache-dtype fp8:减少显存占用
  • VLLM_TORCH_COMPILE=1:启用编译优化
  • VLLM_DISABLE_CUDA_GRAPH=True:某些场景下需要禁用 CUDA Graph
  • --enforce-eager:强制 eager 模式,提升兼容性,但在测试中发现该参数极大降低处理能力(18.4token/s),在调测完成后撤除。

提升 vLLM 处理速度的措施

在部署 vLLM 服务时,除了保证模型稳定运行外,提升推理速度(Token/s)也是关键目标。以下是经过验证的有效提速措施:

1. 启用 Torch Compile

通过设置环境变量 VLLM_TORCH_COMPILE=1,vLLM 会利用 PyTorch 2.0+ 的编译功能对模型算子进行优化,显著减少内核启动开销。实测在 27B 模型上可提升 10%-15% 的推理速度。

2. 使用 FP8 量化模型

相比 BF16 或 FP16,FP8 模型不仅显存占用更低,推理速度也更快。例如 Qwen3.5-27B-FP8 在相同硬件下比全精度版本快约 20%,且精度损失极小。

3. 优化显存利用率

  • 设置 --gpu-memory-utilization 0.95 可最大化显存使用,增加批处理大小(batch size),从而提升吞吐。
  • 注意:过高可能导致 OOM,建议根据实际显存大小微调。

4. 启用分块预填充(Chunked Prefill)

参数 --enable-chunked-prefill 允许将长 prompt 分块处理,避免单次请求占用过多显存,从而支持更大的并发请求数,提升整体吞吐量。

5. 调整批处理参数

  • --max-num-batched-tokens:限制每批次处理的 token 总数,避免显存溢出。
  • --max-num-seqs:限制并发序列数,平衡延迟与吞吐。
  • 适当调大这些参数可在显存允许范围内提升并发处理能力。

6. 使用 FP8 KV Cache

通过 --kv-cache-dtype fp8 将 KV Cache 量化为 FP8,可大幅减少显存占用,从而支持更大的 batch size 或更长的上下文,间接提升推理速度。

7. 移除 Eager 模式

--enforce-eager 会强制模型使用 PyTorch 的 Eager 模式,虽然兼容性好,但会严重降低推理速度(实测下降至 18.4 token/s)。在完成调试后,务必移除该参数以启用图模式加速。

8. 多卡并行策略

  • 使用 --tensor-parallel-size 匹配可用 GPU 数量,确保模型权重均匀分布。
  • 对于小模型(如 0.8B),4 卡并行可能带来额外通信开销,建议根据模型大小选择合适卡数。 最终选用2卡,实际测试效果差不多。但是4卡的KV缓存只有9%利用率,缩减到两卡后利用率提升到27%,空出来两张卡补了一个代码补全的模型。

10. 监控与调优

  • 使用 nvidia-smi 监控显存占用与 GPU 利用率。

通过上述措施,可在保证稳定性的前提下,将 vLLM 的推理速度提升至4卡并发时,单用户50token/s,多用户200token/s以上。
双卡运行时 单用户32 token/s 8用户 263 token/s
最高服务测试 10并发,332 token/s


2026.4.27 补充工具调用参数:
–enable-auto-tool-choice –tool-call-parser hermes
补充后可以在chatBOX上自定义MCP服务器