vLLM与SGLang启动参数调优实战:从默认配置到生产级吞吐量翻倍——Agent推理引擎篇

vllm serve meta-llama/Llama-3.1-8B-Instruct

--gpu-memory-utilization 0.85

激进配置(需要配合小 max-num-seqs)

vllm serve meta-llama/Llama-3.1-8B-Instruct

--gpu-memory-utilization 0.95

--max-num-seqs 32

markdown 复制代码
**调优方法**:先用 0.85 跑通,然后每次 +0.02,直到遇到 OOM 再 -0.02。这个「刚好不 OOM」的值就是你的最优解。

### 2.2 `--max-num-seqs`(并发请求上限)

默认值: 256 V1 建议范围: 32 ~ 128(普通模型)/ 4 ~ 16(DeepSeek-V3 等大模型)

css 复制代码
**这是 V0 → V1 迁移最大的坑**:V1 的 `max_num_seqs` 不能照搬 V0 的值。V1 在 warmup 时为每个 seq 预分配采样器显存,所以 256 这个默认值在 V1 下极易 OOM。

```bash
# V1 安全启动(Llama-8B 单卡)
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --max-num-seqs 64

# V1 + DeepSeek-V3(8×H100)
vllm serve deepseek-ai/DeepSeek-V3 \
  --tensor-parallel-size 8 \
  --max-num-seqs 16 \
  --gpu-memory-utilization 0.85

判断是否需要调整:看日志里的 preemption 告警。

vbnet 复制代码
WARNING: Sequence group 0 is preempted by PreemptionMode.RECOMPUTE
because there is not enough KV cache space.
→ 降低 max-num-seqs 或提高 gpu-memory-utilization

preemption 次数越多 = 实际并发超出了 KV Cache 容量 = 请求被反复踢出再重算 = 延迟暴涨。

2.3 --max-model-len(最大上下文长度)

makefile 复制代码
默认值: 模型理论最大值(如 128K)
建议值: 实际业务需求的最大值

这是新手最常犯的错误 :不设 --max-model-len,vLLM 按模型 config.json 里的理论最大值预分配 KV Cache。一个声称支持 128K 上下文的模型,如果业务只需要 8K,设 128K 会浪费大量显存。

bash 复制代码
# ❌ 默认:按模型理论最大值预分配,浪费显存
vllm serve meta-llama/Llama-3.1-8B-Instruct

# ✅ 按实际业务需求限制
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --max-model-len 8192

实际效果:把 max_model_len 从 131072 降到 8192,KV Cache 可用容量可提升 2-4 倍(取决于模型架构)。

2.4 --max-num-batched-tokens(批处理 token 预算)

lua 复制代码
默认值: 与 max-model-len 一致
建议范围: 4096 ~ 16384

这是 Chunked Prefill 的核心控制参数。V1 默认启用 Chunked Prefill ------ 调度器优先处理 decode 请求,用剩余 token 预算处理 prefill 分块。

效果 适用场景
2048 ~ 4096 ITL(Token 间延迟)最优,prefill 被切更碎 在线聊天,延迟敏感
8192 ~ 16384 TTFT(首 Token 延迟)最优,prefill 一次处理更多 离线批处理
= max-model-len 接近 V0 行为(但仍优先 decode) 简单迁移,不想调
bash 复制代码
# 延迟敏感型(聊天机器人)
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --max-num-batched-tokens 4096 \
  --max-num-seqs 128

# 吞吐优先型(文档批处理)
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --max-num-batched-tokens 16384 \
  --max-num-seqs 256

2.5 优化等级 -O 参数

vLLM V1 提供 4 级优化,控制启动时间与运行性能的权衡:

等级 CUDA Graph 行为 启动时间 运行吞吐
-O0 无 CUDA Graph 最快 最低
-O1 Piecewise CUDA Graph 较快 中等
-O2(默认) Full + Piecewise CUDA Graph 较慢 最高
-O3 暂同 -O2 同 -O2 同 -O2
bash 复制代码
# 开发调试用 -O0(秒级启动)
vllm serve model --optimization-level 0

# 生产用默认 -O2 即可
vllm serve model  # --optimization-level 2 是默认值

避坑-O0 下禁用 CUDA Graph 后吞吐会下降 30-50%,仅用于「我要快速测试模型能不能加载」的场景,不要在生产环境用。

2.6 并行策略速查

策略 参数 何时用
张量并行 --tensor-parallel-size N 模型放不进单卡
流水线并行 --pipeline-parallel-size N 跨节点超大模型
专家并行 --enable-expert-parallel MoE 模型(DeepSeek/Qwen3MoE)
数据并行 --data-parallel-size N 多副本提吞吐

关键认知:数据并行的吞吐扩展效率远高于张量并行。如果单卡能放下模型,用 8×DP 比 1×TP8 吞吐高得多。


三、SGLang 六大核心参数逐一拆解

SGLang 是 DeepSeek 官方推荐的推理引擎,它在 vLLM 的参数体系上多了几个独有的调优旋钮。

3.1 --mem-fraction-static(SGLang 版显存分配)

makefile 复制代码
默认值: 自动计算(保守)
建议范围: 0.80 ~ 0.92

与 vLLM 的 --gpu-memory-utilization 同概念,但 SGLang 的自动推断偏保守。看服务器启动日志:

ini 复制代码
max_total_num_tokens=665690, chunked_prefill_size=8192,
max_prefill_tokens=16384, max_running_requests=4096,
context_len=65536, available_gpu_mem=13.50 GB

判断标准

  • available_gpu_mem 在 5-8 GB → 刚好,不用调
  • available_gpu_mem > 10 GB → 太保守,提高 --mem-fraction-static
  • available_gpu_mem < 5 GB → 太激进,降低 --mem-fraction-static
bash 复制代码
# 如果日志显示 available_gpu_mem=13.50 GB(太保守)
python3 -m sglang.launch_server \
  --model-path deepseek-ai/DeepSeek-R1 \
  --tp 8 \
  --mem-fraction-static 0.90  # 从默认值提高

3.2 --schedule-conservativeness(SGLang 独有,最重要)

makefile 复制代码
默认值: 1.0
建议范围: 0.3(激进) ~ 1.5(保守)

这是 SGLang 区别于 vLLM 的最大特色。它控制调度器在接受新请求时的「冒险程度」。

看 SGLang 的运行时日志:

yaml 复制代码
Decode batch. #running-req: 233, #token: 370959,
token usage: 0.82, cuda graph: True,
gen throughput (token/s): 4594.01, #queue-req: 317
指标 含义 健康范围
token usage KV Cache 利用率 > 0.9
#queue-req 排队请求数 100 ~ 2000
#running-req 正在处理的请求 接近 --max-running-requests

诊断决策树

lua 复制代码
token usage < 0.9 且 #queue-req > 0
  → 调度器太保守,KV Cache 没用满,请求在排队
  → 降低 --schedule-conservativeness 到 0.3

token usage 接近 1.0 且频繁出现:
  "KV cache pool is full. Retract requests."
  → 调度器太激进,频繁踢请求重算
  → 提高 --schedule-conservativeness 到 1.3
bash 复制代码
# 离线批处理(吞吐优先,激进调度)
python3 -m sglang.launch_server \
  --model-path Qwen/Qwen2.5-72B-Instruct \
  --tp 4 \
  --schedule-conservativeness 0.3 \
  --mem-fraction-static 0.90

# 在线服务(延迟优先,保守调度)
python3 -m sglang.launch_server \
  --model-path Qwen/Qwen2.5-72B-Instruct \
  --tp 4 \
  --schedule-conservativeness 1.3 \
  --max-running-requests 128

3.3 --cuda-graph-max-bs(CUDA Graph 批量覆盖)

makefile 复制代码
默认值: 160 ~ 256(视模型而定)
建议范围: 256 ~ 768

CUDA Graph 把一系列 CUDA kernel 调用录制下来重放,消除逐 kernel 提交的开销。默认只覆盖小批量------如果你的实际并发经常超过 256,增加这个值可以显著提吞吐。

bash 复制代码
# 大 TP 推理场景(如 TP=8)扩大 CUDA Graph 覆盖
python3 -m sglang.launch_server \
  --model-path deepseek-ai/DeepSeek-R1 \
  --tp 8 \
  --cuda-graph-max-bs 512 \
  --mem-fraction-static 0.85  # CUDA Graph 吃显存,需同步调低

CUDA Graph + torch.compile 叠加效果(DeepSeek-V3, batch_size=1, 256 input / 32 output tokens):

配置 总延迟 吞吐 (token/s)
无优化 7.322 s 39.34
CUDA Graph 1.256 s 229.27
CUDA Graph + torch.compile 1.011 s 284.86

从 39 token/s 到 285 token/s,纯靠启动参数,不换硬件不动模型。

3.4 --max-running-requests(并发上限)

makefile 复制代码
默认值: 自动计算
建议范围: 取决于显存

与 vLLM 的 --max-num-seqs 对应。如果出现 OOM:

OOM 类型 调整方向
Prefill 阶段 OOM 降低 --chunked-prefill-size 到 4096 或 2048
Decode 阶段 OOM 降低 --max-running-requests
通用 OOM 降低 --mem-fraction-static 到 0.80
bash 复制代码
# 长上下文场景:小 chunk、少并发、大 KV Cache
python3 -m sglang.launch_server \
  --model-path meta-llama/Llama-3.1-8B-Instruct \
  --context-length 32768 \
  --chunked-prefill-size 4096 \
  --max-running-requests 64 \
  --mem-fraction-static 0.88

3.5 --tp-size vs --dp-size(并行策略)

SGLang 把张量并行和数据并行分开暴露:

bash 复制代码
# 数据并行优先(吞吐最大化):单卡放得下模型时
python3 -m sglang.launch_server \
  --model-path Qwen/Qwen2.5-7B-Instruct \
  --dp-size 8  # 8 个副本,8× 吞吐

# 张量并行(模型放不下时)
python3 -m sglang.launch_server \
  --model-path Qwen/Qwen2.5-72B-Instruct \
  --tp-size 4  # 4 卡拼一个模型

# DeepSeek 专用:DP Attention(MLA 架构关键优化)
python3 -m sglang.launch_server \
  --model-path deepseek-ai/DeepSeek-R1 \
  --tp-size 8 \
  --dp-size 8 \
  --enable-dp-attention

DP Attention 的原理 :MLA(Multi-head Latent Attention)的 KV Cache 只有 1 个 head,TP 无法切分,每卡存一份完整 KV Cache。开启 --enable-dp-attention 后,请求按 DP 维度分布,每张卡只维护自己那份请求的 KV Cache,显存效率大幅提升。

3.6 SGLang 专属加速选项

参数 适用场景 代价
--enable-torch-compile 小模型 + 小批量 首次启动编译时间 + 显存
--quantization fp8 支持 FP8 的模型 精度微降
--enable-flashinfer-mla DeepSeek 模型 需装 flashinfer
--speculative-algo NEXTN DeepSeek-V3/R1 需加载 draft 模型
--schedule-policy lpm 共享前缀多的场景 调度开销
--enable-hierarchical-cache 长上下文场景 需配置存储后端
bash 复制代码
# DeepSeek-R1 性能全开配置(8×H200)
python3 -m sglang.launch_server \
  --model-path deepseek-ai/DeepSeek-R1 \
  --tp 8 \
  --trust-remote-code \
  --enable-dp-attention \
  --dp-size 8 \
  --cuda-graph-max-bs 512 \
  --mem-fraction-static 0.85 \
  --enable-flashinfer-mla \
  --enable-torch-compile \
  --torch-compile-max-bs 32 \
  --speculative-algo NEXTN \
  --speculative-draft SGLang/DeepSeek-V3-NextN \
  --speculative-num-steps 2 \
  --speculative-eagle-topk 4 \
  --speculative-num-draft-tokens 4

四、vLLM vs SGLang 参数对照速查表

调优维度 vLLM 参数 SGLang 参数 说明
显存分配 --gpu-memory-utilization --mem-fraction-static 越高吞吐越大,但越容易 OOM
并发上限 --max-num-seqs --max-running-requests V1 不能用 V0 的 256
批处理 Token --max-num-batched-tokens --chunked-prefill-size 小值=低延迟,大值=高 TTFT
上下文长度 --max-model-len --context-length 按实际需求设,别用理论最大值
CUDA Graph -O 优化等级控制 --cuda-graph-max-bs SGLang 可独立调整批量覆盖
张量并行 --tensor-parallel-size --tp-size 模型放不进单卡时用
数据并行 --data-parallel-size --dp-size 吞吐扩展首选
调度策略 N/A(固定) --schedule-conservativeness SGLang 独有
前缀调度 自动 prefix caching --schedule-policy lpm SGLang 需显式开启
CPU NUMA --numa-bind N/A vLLM 独有
torch.compile -O 等级内包含 --enable-torch-compile SGLang 需显式开启

五、三种典型场景的推荐配置

场景 A:在线聊天/Agent 服务(低延迟优先)

目标:P95 延迟 < 1s,ITL < 50ms

vLLM 配置(Llama-3.1-8B,单卡 H100):

bash 复制代码
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --max-model-len 8192 \
  --gpu-memory-utilization 0.85 \
  --max-num-seqs 64 \
  --max-num-batched-tokens 4096 \
  --optimization-level 2

SGLang 配置

bash 复制代码
python3 -m sglang.launch_server \
  --model-path meta-llama/Llama-3.1-8B-Instruct \
  --context-length 8192 \
  --mem-fraction-static 0.85 \
  --max-running-requests 128 \
  --cuda-graph-max-bs 256 \
  --schedule-conservativeness 1.2 \
  --attention-backend fa3

场景 B:离线文档批处理(吞吐优先)

目标:最大化 token/s,延迟可以妥协

vLLM 配置(Qwen2.5-72B,4×H100):

bash 复制代码
vllm serve Qwen/Qwen2.5-72B-Instruct \
  --tensor-parallel-size 4 \
  --max-model-len 32768 \
  --gpu-memory-utilization 0.92 \
  --max-num-seqs 256 \
  --max-num-batched-tokens 16384 \
  --optimization-level 2

SGLang 配置

bash 复制代码
python3 -m sglang.launch_server \
  --model-path Qwen/Qwen2.5-72B-Instruct \
  --tp-size 4 \
  --context-length 32768 \
  --mem-fraction-static 0.90 \
  --max-running-requests 4096 \
  --chunked-prefill-size 16384 \
  --cuda-graph-max-bs 512 \
  --schedule-conservativeness 0.3

场景 C:DeepSeek-V3/R1 生产部署

目标:在 8×H200 上跑起来且不 OOM

bash 复制代码
# SGLang(DeepSeek 官方推荐引擎)
python3 -m sglang.launch_server \
  --model-path deepseek-ai/DeepSeek-R1 \
  --tp 8 \
  --trust-remote-code \
  --enable-dp-attention \
  --dp-size 8 \
  --mem-fraction-static 0.85 \
  --cuda-graph-max-bs 512 \
  --max-running-requests 256 \
  --chunked-prefill-size 8192 \
  --context-length 32768 \
  --enable-flashinfer-mla

# vLLM(备选,V1 引擎)
vllm serve deepseek-ai/DeepSeek-R1 \
  --tensor-parallel-size 8 \
  --max-model-len 32768 \
  --gpu-memory-utilization 0.80 \
  --max-num-seqs 16 \
  --max-num-batched-tokens 8192 \
  --enable-expert-parallel

六、调参方法论:四步走

第一步:跑通基准

先用保守参数把模型跑起来,记录基线吞吐:

bash 复制代码
# vLLM 压测
python3 -m vllm.benchmarks.serve \
  --model your-model \
  --dataset-name random \
  --random-input-len 1024 \
  --random-output-len 256 \
  --num-prompts 500

# SGLang 压测
python3 -m sglang.bench_serving \
  --backend sglang \
  --dataset-name random \
  --random-input 1024 \
  --random-output 256 \
  --num-prompts 500 \
  --host 127.0.0.1 --port 30000

第二步:最大化 KV Cache

逐步提高 --gpu-memory-utilization / --mem-fraction-static,每次 +0.02,压测一轮,直到出现 OOM 再回退 0.02。这是投入产出比最高的单步操作。

第三步:扩大 CUDA Graph 覆盖

--cuda-graph-max-bs 从默认翻倍(如 256→512),同时将显存分配参数下调 0.02-0.03(因为 CUDA Graph 缓冲区吃显存)。对比吞吐变化。

第四步:场景化微调

根据你的场景选型:

  • 在线服务 → 关注 P95 延迟,降低 max-num-seqs/max-running-requests
  • 离线批处理 → 关注 token/s,提高并发上限 + 激进调度(SGLang 降低 conservativeness)
  • 长上下文 → 设实际 max-model-len,降低 chunked-prefill-size

七、常见踩坑汇总

现象 修复
V1 默认 max-num-seqs=256 warmup OOM 降到 32-64
max-model-len 用理论最大值 KV Cache 极小、频繁 preemption 设为实际业务需求值
CUDA Graph 没覆盖实际批量 日志 cuda graph: False,吞吐偏低 提高 --cuda-graph-max-bs
SGLang schedule-conservativeness 默认值 KV Cache 利用率 < 0.9 且排队多 降到 0.3
DeepSeek 没开 DP Attention 每卡存一份完整 KV Cache,显存浪费 --enable-dp-attention --dp-size 8
多 socket 服务器跨 NUMA GPU 间通信延迟高 vLLM 加 --numa-bind
CPU 核心不够(<2+N) GPU 利用率低 vLLM 至少 2+N 物理核心(N=GPU 数)
开了 speculative decoding 但没配参数 启动失败 SGLang 必须同时配 --speculative-draft

八、总结

调参的本质是显存在四个池子之间做权衡。优先级从高到低:

  1. 设对 max-model-len/context-length------这是最容易白捡的显存
  2. 调高显存分配比例------从默认值往上探,找到 OOM 临界点
  3. 扩大 CUDA Graph 覆盖------从默认 256 提到 512/768
  4. 场景化微调并发和调度------在线降并发、离线提并发、SGLang 调 conservativeness
  5. 按需加加速选项------FP8 量化、torch.compile、speculative decoding

记住:不换硬件、不动模型、只改启动参数,吞吐量翻 3-5 倍是完全可行的。 上面的 CUDA Graph 基准就是证据:DeepSeek-V3 从 39 token/s 到 285 token/s,靠的只是几个 flag。

相关推荐
starrysky8102 小时前
【03】ImportError: cannot import name 'X' —— 模块在,名字没了
angular.js
starrysky8102 小时前
systemd-journald日志限速导致生产日志丢失:Suppressed XXXX messages完整排查
angular.js
Jolyne_2 天前
Angular基础速通
前端·angular.js
starrysky8102 天前
Agent 的终端安全怎么做?6 种沙箱后端 + 危险命令审批 + sudo 无痕处理的完整拆解
angular.js
starrysky8102 天前
Flash Attention 安装地狱六重崩溃:CUDA_HOME not set、undefined symbol、预编译轮子不兼容、pip 编译两小时失败——逐一击破
angular.js
starrysky8103 天前
nvidia-smi 显示 8GB 空闲,为什么 PyTorch 报 CUDA out of memory?——CUDA 缓存分配器底层原理
angular.js
starrysky8106 天前
Ollama 部署五大崩溃:llama runner terminated exit 2、10分钟后停止服务、GGUF断言失败——逐一修复
angular.js
starrysky8108 天前
ACP 不是 MCP 的平替:拆解 Claude Code 的子进程 Agent 架构——与 OpenClaw、Hermes 的三角对照
angular.js
starrysky81013 天前
被忽视的Django生产陷阱:为什么ALLOWED_HOSTS通配符救不了你——DisallowedHost根因排查与中间件修复
angular.js