VLLM V1性能优化指南1
本文档基于vLLM 0.11.1源代码深入分析,提供V1架构的全面性能优化参数、配置示例和最佳实践。适用版本: vLLM V1架构 vllm 0.11.1。
1. V1完整参数配置表
快速导航: 本章提供vLLM 0.11.1 V1版本所有可用性能优化参数的完整列表。通过表格快速查找所需参数,了解默认值、性能影响和V1特性标识。
1.1 核心引擎参数(EngineArgs)
1.1.1 调度器配置参数
| 参数名 |
类型 |
默认值 |
说明 |
性能影响 |
V1特性 |
| max_num_batched_tokens |
int |
根据场景自动推断 |
单次迭代处理的最大token数 |
影响吞吐量/延迟平衡 |
✅ |
| max_num_seqs |
int |
根据场景自动推断 |
单次迭代处理的最大序列数 |
影响并发能力 |
✅ |
| max_model_len |
int |
自动从模型推断 |
模型最大序列长度(prompt+output) |
影响内存分配 |
✅ |
| enable_chunked_prefill |
bool |
None |
启用分块prefill处理长序列 |
长上下文必需 |
✅ |
| max_num_partial_prefills |
int |
1 |
并发partial prefill数量 |
V1并发优化 |
✅ V1 |
| max_long_partial_prefills |
int |
1 |
并发长partial prefill数量 |
V1长上下文优化 |
✅ V1 |
| long_prefill_token_threshold |
int |
0 |
长prefill的token阈值 |
V1阈值控制 |
✅ V1 |
| scheduling_policy |
str |
“fcfs” |
调度策略: fcfs/priority |
延迟优化 |
✅ V1 |
| scheduler_cls |
str/type |
None |
自定义调度器类 |
高级定制 |
✅ V1 |
| async_scheduling |
bool |
False |
启用V1异步调度 |
V1性能提升5-15% |
✅ V1 |
| num_lookahead_slots |
int |
0 |
预测推测解码的slot数 |
推测解码 |
✅ |
| disable_hybrid_kv_cache_manager |
bool |
False |
禁用混合KV缓存管理器 |
调试用 |
✅ V1 |
| disable_chunked_mm_input |
bool |
False |
禁用多模态输入分块 |
多模态优化 |
✅ |
1.1.2 内存配置参数
| 参数名 |
类型 |
默认值 |
说明 |
性能影响 |
V1特性 |
| gpu_memory_utilization |
float |
0.9 |
GPU内存使用率(0-1) |
内存分配核心 |
✅ |
| kv_cache_memory_bytes |
int |
None |
精确指定KV Cache字节数 |
精细控制 |
✅ |
| swap_space |
float |
4 |
CPU swap空间(GiB) |
防止OOM |
✅ |
| cpu_offload_gb |
float |
0 |
CPU offload大小(GiB) |
超大模型 |
✅ |
| enable_prefix_caching |
bool |
None |
启用prefix缓存 |
重复prompt加速 |
✅ V1默认启用 |
| prefix_caching_hash_algo |
str |
“sha256” |
prefix缓存哈希算法 |
缓存一致性 |
✅ |
| cache_dtype |
str |
“auto” |
KV Cache数据类型 |
内存优化 |
✅ |
| calculate_kv_scales |
bool |
False |
动态计算FP8 KV scale |
FP8优化 |
✅ |
| kv_sharing_fast_prefill |
bool |
False |
KV共享快速prefill(实验性) |
实验功能 |
✅ |
| kv_offloading_size |
float |
None |
KV offload缓冲区大小(GiB) |
长上下文offload |
✅ |
| kv_offloading_backend |
str |
None |
KV offload后端: native/lmcache |
offload后端选择 |
✅ |
| num_gpu_blocks_override |
int |
None |
覆盖GPU blocks数量 |
测试/调试 |
✅ |
| block_size |
int |
平台自动推断 |
cache block大小(tokens) |
内存粒度 |
✅ |
| mamba_block_size |
int |
None |
Mamba cache block大小 |
Mamba模型 |
✅ |
| mamba_cache_dtype |
str |
“auto” |
Mamba缓存数据类型 |
Mamba优化 |
✅ |
1.1.3 模型配置参数
| 参数名 |
类型 |
默认值 |
说明 |
性能影响 |
V1特性 |
| model |
str |
必需 |
模型路径或HF repo_id |
- |
✅ |
| tokenizer |
str |
None |
tokenizer路径(默认同model) |
- |
✅ |
| dtype |
str |
“auto” |
模型数据类型: auto/float16/bfloat16 |
性能/精度 |
✅ |
| quantization |
str |
None |
量化方法: fp8/awq/gptq等 |
内存节省 |
✅ |
| max_logprobs |
int |
20 |
最大logprobs数量 |
输出控制 |
✅ |
| enforce_eager |
bool |
False |
强制eager模式(禁用CUDA Graph) |
调试/兼容 |
✅ |
| disable_sliding_window |
bool |
False |
禁用滑动窗口注意力 |
长上下文 |
✅ |
| revision |
str |
None |
模型版本/分支 |
- |
✅ |
| logits_processors |
list |
None |
自定义logits处理器列表 |
高级定制 |
✅ V1 |
| override_attention_dtype |
str |
None |
覆盖注意力数据类型 |
性能调优 |
✅ |
1.1.4 并行化配置参数
| 参数名 |
类型 |
默认值 |
说明 |
性能影响 |
V1特性 |
| tensor_parallel_size |
int |
1 |
张量并行大小 |
大模型必需 |
✅ |
| pipeline_parallel_size |
int |
1 |
流水线并行大小 |
超大模型 |
✅ |
| data_parallel_size |
int |
1 |
数据并行大小 |
高吞吐量 |
✅ |
| distributed_executor_backend |
str |
None |
分布式后端: ray/mp/uni |
分布式执行 |
✅ |
| enable_expert_parallel |
bool |
False |
启用专家并行(MoE) |
MoE模型 |
✅ |
| enable_eplb |
bool |
False |
启用专家并行负载均衡 |
MoE优化 |
✅ |
| disable_custom_all_reduce |
bool |
False |
禁用自定义all-reduce |
兼容性 |
✅ |
1.1.5 CUDA编译配置参数
| 参数名 |
类型 |
默认值 |
说明 |
性能影响 |
V1特性 |
| compilation_config |
dict/Config |
自动 |
CUDA编译配置对象 |
CUDA优化核心 |
✅ V1 |
| cudagraph_mode |
str |
“FULL_AND_PIECEWISE” |
CUDA Graph模式 |
性能提升关键 |
✅ V1 |
| cudagraph_capture_sizes |
list |
自动 |
CUDA Graph捕获大小列表 |
图编译粒度 |
✅ V1 |
| max_cudagraph_capture_size |
int |
256 |
最大CUDA Graph捕获大小 |
图编译上限 |
✅ V1 |
| cudagraph_num_of_warmups |
int |
0 |
CUDA Graph预热次数 |
图编译稳定性 |
✅ V1 |
| mode |
int |
0 |
编译模式: 0=disabled, 3=inductor |
Torch Compile |
✅ V1 |
| backend |
str |
“inductor” |
编译后端 |
编译器选择 |
✅ V1 |
1.1.6 多模态配置参数
| 参数名 |
类型 |
默认值 |
说明 |
性能影响 |
V1特性 |
| limit_mm_per_prompt |
dict |
{} |
每个prompt的多模态限制 |
多模态控制 |
✅ |
| enable_mm_embeds |
bool |
False |
启用多模态嵌入 |
多模态功能 |
✅ |
| mm_processor_kwargs |
dict |
None |
多模态处理器参数 |
多模态定制 |
✅ |
| mm_processor_cache_gb |
float |
4 |
多模态处理器缓存(GiB) |
多模态性能 |
✅ |
| mm_processor_cache_type |
str |
None |
多模态缓存类型 |
缓存策略 |
✅ |
| skip_mm_profiling |
bool |
False |
跳过多模态profiling |
启动速度 |
✅ |
1.1.7 推测解码配置
| 参数名 |
类型 |
默认值 |
说明 |
性能影响 |
V1特性 |
| speculative_config |
dict |
None |
推测解码配置 |
延迟优化 |
✅ |
| speculative_model |
str |
None |
推测模型路径 |
推测解码 |
✅ |
| num_speculative_tokens |
int |
None |
推测token数量 |
推测粒度 |
✅ |
1.1.8 LoRA配置参数
| 参数名 |
类型 |
默认值 |
说明 |
性能影响 |
V1特性 |
| enable_lora |
bool |
False |
启用LoRA适配器 |
多任务 |
✅ |
| max_loras |
int |
1 |
最大LoRA数量 |
LoRA并发 |
✅ |
| max_lora_rank |
int |
16 |
最大LoRA rank |
LoRA容量 |
✅ |
| fully_sharded_loras |
bool |
False |
完全分片LoRA |
LoRA内存 |
✅ |
| max_cpu_loras |
int |
None |
CPU缓存LoRA数量 |
LoRA缓存 |
✅ |
1.2 V1专属环境变量
1.2.1 核心V1控制变量
| 环境变量 |
类型 |
默认值 |
说明 |
性能影响 |
设置方式 |
| VLLM_USE_V1 |
bool |
True |
启用V1架构 |
V1总开关 |
export VLLM_USE_V1=1 |
| VLLM_ENABLE_V1_MULTIPROCESSING |
bool |
True |
启用V1多进程模式 |
V1并行执行 |
export VLLM_ENABLE_V1_MULTIPROCESSING=1 |
| VLLM_WORKER_MULTIPROC_METHOD |
str |
“fork” |
多进程方法: fork/spawn |
V1进程管理 |
export VLLM_WORKER_MULTIPROC_METHOD=spawn |
| VLLM_V1_OUTPUT_PROC_CHUNK_SIZE |
int |
128 |
V1输出处理chunk大小 |
V1流式输出 |
export VLLM_V1_OUTPUT_PROC_CHUNK_SIZE=256 |
| VLLM_V1_USE_PREFILL_DECODE_ATTENTION |
bool |
False |
V1 prefill/decode分离注意力 |
V1注意力优化 |
export VLLM_V1_USE_PREFILL_DECODE_ATTENTION=1 |
| VLLM_V1_USE_OUTLINES_CACHE |
bool |
False |
V1启用outlines缓存 |
V1结构化输出 |
export VLLM_V1_USE_OUTLINES_CACHE=1 |
1.2.2 调度与并发变量
| 环境变量 |
类型 |
默认值 |
说明 |
性能影响 |
| VLLM_ALLOW_LONG_MAX_MODEL_LEN |
bool |
False |
允许超长max_model_len |
长上下文 |
| VLLM_LOG_BATCHSIZE_INTERVAL |
float |
-1 |
batch size日志间隔(秒) |
- 监控 |
| VLLM_SLEEP_WHEN_IDLE |
bool |
False |
空闲时睡眠 |
节能 |
1.2.3 CUDA编译变量
| 环境变量 |
类型 |
默认值 |
说明 |
性能影响 |
| VLLM_DISABLE_COMPILE_CACHE |
bool |
False |
禁用编译缓存 |
开发调试 |
| VLLM_USE_AOT_COMPILE |
bool |
False |
启用AOT编译 |
启动优化 |
| VLLM_FORCE_AOT_LOAD |
bool |
False |
强制AOT加载 |
AOT调试 |
| VLLM_USE_STANDALONE_COMPILE |
bool |
True |
独立编译进程 |
编译稳定性 |
| VLLM_ENABLE_CUDAGRAPH_GC |
bool |
False |
启用CUDA Graph GC |
内存回收 |
| VLLM_ENABLE_INDUCTOR_MAX_AUTOTUNE |
bool |
True |
Inductor最大自动调优 |
编译优化 |
| VLLM_ENABLE_INDUCTOR_COORDINATE_DESCENT_TUNING |
bool |
True |
Inductor坐标下降调优 |
编译优化 |
1.2.4 内存管理变量
| 环境变量 |
类型 |
默认值 |
说明 |
性能影响 |
| VLLM_CPU_KVCACHE_SPACE |
int |
0 |
CPU KV Cache空间(GB) |
CPU backend |
| VLLM_ALLOW_CHUNKED_LOCAL_ATTN_WITH_HYBRID_KV_CACHE |
bool |
False |
允许分块局部注意力与混合KV |
高级优化 |
| VLLM_KV_EVENTS_USE_INT_BLOCK_HASHES |
bool |
True |
KV events使用整数哈希 |
缓存效率 |
1.2.5 注意力后端变量
| 环境变量 |
类型 |
默认值 |
说明 |
性能影响 |
| VLLM_ATTENTION_BACKEND |
str |
None |
注意力后端: FLASH_ATTN/XFORMERS等 |
注意力性能 |
| VLLM_USE_TRITON_FLASH_ATTN |
bool |
True |
使用Triton FlashAttention |
注意力实现 |
| VLLM_DISABLE_FLASHINFER_PREFILL |
bool |
False |
禁用FlashInfer prefill |
注意力后端 |
| VLLM_USE_FLASHINFER_SAMPLER |
bool |
None |
使用FlashInfer sampler |
采样性能 |
| VLLM_FLASH_ATTN_VERSION |
int |
None |
FlashAttention版本 |
版本选择 |
| VLLM_FLASH_ATTN_MAX_NUM_SPLITS_FOR_CUDA_GRAPH |
int |
32 |
CUDA Graph最大分片数 |
图编译限制 |
| VLLM_USE_CUDNN_PREFILL |
bool |
False |
使用cuDNN prefill |
注意力后端 |
1.2.6 性能监控变量
| 环境变量 |
类型 |
默认值 |
说明 |
性能影响 |
| VLLM_TORCH_PROFILER_DIR |
str |
None |
Torch profiler输出目录 |
- 性能分析 |
| VLLM_TORCH_CUDA_PROFILE |
bool |
False |
启用CUDA profiling |
- CUDA分析 |
| VLLM_CUSTOM_SCOPES_FOR_PROFILING |
bool |
False |
自定义profiling作用域 |
- 详细分析 |
| VLLM_NVTX_SCOPES_FOR_PROFILING |
bool |
False |
NVTX profiling作用域 |
- NVIDIA工具 |
1.2.7 高级优化变量
| 环境变量 |
类型 |
默认值 |
说明 |
性能影响 |
| VLLM_FUSED_MOE_CHUNK_SIZE |
int |
65536 |
MoE融合chunk大小 |
MoE性能 |
| VLLM_ENABLE_FUSED_MOE_ACTIVATION_CHUNKING |
bool |
True |
MoE激活分块 |
MoE优化 |
| VLLM_USE_FUSED_MOE_GROUPED_TOPK |
bool |
True |
MoE分组topk |
MoE选择 |
| VLLM_MOE_DP_CHUNK_SIZE |
int |
256 |
MoE DP chunk大小 |
MoE并行 |
| VLLM_ALL2ALL_BACKEND |
str |
“allgather_reducescatter” |
All2All通信后端 |
MoE通信 |
1.3 参数调优速查表
按优化目标选择参数
| 优化目标 |
关键参数 |
推荐值 |
次要参数 |
| 最大吞吐量 |
max_num_batched_tokens |
16384-32768 |
max_num_seqs=256 async_scheduling=True max_num_partial_prefills=8 |
| 最低延迟 |
max_num_batched_tokens |
2048-4096 |
max_num_seqs=32 scheduling_policy=”priority” cudagraph_mode=FULL |
| 长上下文 |
max_model_len |
16384-32768+ |
kv_cache_dtype=”fp8” enable_chunked_prefill=True max_long_partial_prefills=4 |
| 高并发 |
max_num_seqs |
128-512 |
max_num_batched_tokens=16384 async_scheduling=True enable_prefix_caching=True |
| 节省内存 |
gpu_memory_utilization |
0.85-0.90 |
kv_cache_dtype=”fp8” quantization=”fp8” max_model_len合理设置 |
V1特性启用清单
1 2 3 4 5 6 7 8 9
| # 标准V1配置 export VLLM_USE_V1=1 # 必需 export VLLM_ENABLE_V1_MULTIPROCESSING=1 # 推荐 export VLLM_WORKER_MULTIPROC_METHOD=spawn # Windows必需
# Python配置 async_scheduling=True # V1核心优化(+5-15%性能) max_num_partial_prefills=4 # V1并发优化 cudagraph_mode=FULL_AND_PIECEWISE # V1默认模式
|
1.4 常见问题参数排查
| 问题 |
检查参数 |
解决方案 |
| OOM |
gpu_memory_utilization max_model_len kv_cache_dtype |
降低到0.85-0.90 减小到实际需求 使用”fp8” |
| 吞吐量低 |
max_num_batched_tokens async_scheduling enable_chunked_prefill |
增大到16384-32768 设置True 启用 |
| 延迟高 |
max_num_seqs scheduling_policy cudagraph_mode |
减小到32-64 “priority” FULL |
| 长序列卡顿 |
enable_chunked_prefill max_num_partial_prefills |
必须True 增加到4-8 |
| V1功能未生效 |
VLLM_USE_V1 async_scheduling |
export=1 设置True |
2. 性能优化策略总结
快速导航: 本章提供系统化的优化框架、决策矩阵和分层优化策略,帮助快速制定优化方案。
2.1 优化策略分类框架
vLLM性能优化可以从以下6个维度进行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| vLLM性能优化 ├── 1. 内存优化 │ ├─ GPU内存使用率调整 │ ├─ KV Cache精确控制 │ ├─ 量化技术 (FP8/AWQ/GPTQ) │ └─ CPU Offload & KV Offload │ ├── 2. 吞吐量优化 │ ├─ Batch Size调整 │ ├─ Continuous Batching │ ├─ Chunked Prefill │ └─ 并发请求数优化 │ ├── 3. 延迟优化 │ ├─ 小Batch Size │ ├─ Chunked Prefill │ ├─ 优先级调度 │ └─ Speculative Decoding │ ├── 4. 并行化优化 │ ├─ Tensor Parallelism (TP) │ ├─ Pipeline Parallelism (PP) │ ├─ Data Parallelism (DP) │ └─ Expert Parallelism (EP) │ ├── 5. CUDA优化 │ ├─ CUDA Graph (FULL/PIECEWISE) │ ├─ Torch Compile │ ├─ FlashAttention选择 │ └─ FP8 CUDA Kernel │ └── 6. 缓存优化 ├─ Prefix Caching ├─ 多模态缓存 ├─ Encoder Cache └─ KV Sharing
|
2.2 快速决策矩阵
按优化目标选择策略:
| 优化目标 |
首选策略 |
次选策略 |
进阶策略 |
预期提升 |
| 最大化吞吐量 |
Batch Size增大 |
Chunked Prefill |
Prefix Caching |
+20-50% |
| 最小化延迟 |
Batch Size减小 |
优先级调度 |
CUDA Graph FULL |
-20-40% |
| 节省GPU内存 |
FP8量化 |
降低max_model_len |
KV Offload |
-30-50% |
| 支持长上下文 |
Chunked Prefill |
FP8 KV Cache |
RoPE Scaling |
2-8x扩展 |
| 提高并发数 |
优化max_num_seqs |
内存优化 |
Data Parallelism |
+50-200% |
2.3 分层优化策略
Level 1 - 基础优化(必做)
立即生效,最小代价:
1 2 3 4 5 6 7 8
| from vllm import LLM
llm = LLM( model="meta-llama/Llama-2-70b-hf", gpu_memory_utilization=0.90, # 1. 合理内存使用率 max_model_len=8192, # 2. 合理上下文长度 tensor_parallel_size=4, # 3. 基础并行配置 )
|
Level 2 - 进阶优化(推荐)
需要一定调试,显著提升:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| from vllm import LLM from vllm.config import CompilationConfig, CUDAGraphMode
llm = LLM( model="meta-llama/Llama-2-70b-hf", # Level 1配置 gpu_memory_utilization=0.92, max_model_len=8192, tensor_parallel_size=4, # 4. Chunked Prefill enable_chunked_prefill=True, max_num_batched_tokens=16384, max_num_partial_prefills=4, # V1特性 # 5. Prefix Caching enable_prefix_caching=True, # 6. CUDA Graph compilation_config=CompilationConfig( cudagraph_mode=CUDAGraphMode.FULL_AND_PIECEWISE, ), # 7. V1异步调度 async_scheduling=True, )
|
Level 3 - 高级优化(专家级)
需要深入调优,极限性能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| import os from vllm import LLM from vllm.config import CompilationConfig, CUDAGraphMode
# 环境变量配置 os.environ["VLLM_USE_V1"] = "1" os.environ["VLLM_ENABLE_V1_MULTIPROCESSING"] = "1"
llm = LLM( model="meta-llama/Llama-2-70b-hf", # Level 1+2配置 gpu_memory_utilization=0.95, max_model_len=8192, tensor_parallel_size=4, enable_chunked_prefill=True, max_num_batched_tokens=16384, enable_prefix_caching=True, async_scheduling=True, # 8. FP8量化 (H100) quantization="fp8", kv_cache_dtype="fp8", # 9. 高级CUDA Graph配置 compilation_config=CompilationConfig( cudagraph_mode=CUDAGraphMode.FULL_AND_PIECEWISE, cudagraph_capture_sizes=[1, 2, 4, 8, 16, 24, 32, 40, 48, 56, 64], max_cudagraph_capture_size=128, cudagraph_num_of_warmups=3, mode=3, # Torch Compile backend="inductor", ), # 10. 细粒度V1控制 max_num_partial_prefills=8, max_long_partial_prefills=4, long_prefill_token_threshold=2048, scheduling_policy="priority", )
|
2.4 关键参数快速参考
GPU内存优化参数
gpu_memory_utilization: 0.90-0.95
kv_cache_dtype: “fp8” (H100)
max_model_len: 按需设置
quantization: “fp8”/“awq”
吞吐量优化参数
max_num_seqs: 128-512
max_num_batched_tokens: 8192-32768
enable_chunked_prefill: True
async_scheduling: True (V1)
延迟优化参数
max_num_seqs: 32-64
scheduling_policy: “priority”
cudagraph_mode: FULL
2.5 常见场景配置模板
详见第13章 V1场景配置模板。
2.6 优化流程与检查清单
5步优化流程:
- 现状评估 - 监控GPU利用率、吞吐量、延迟
- 确定目标 - 最大吞吐量/最低延迟/长上下文/节省内存
- 应用策略 - Level 1→2→3递进优化
- 测试验证 - 基准测试对比优化前后
- 监控调优 - 根据Prometheus数据持续改进
3. GPU内存优化
3.1.1调整GPU内存使用率
问题
默认的GPU内存使用率(90%)在某些场景下可能导致OOM或者内存浪费。
优化建议
提高内存使用率(适用于专用推理服务器):
1 2 3 4 5 6 7
| from vllm import LLM, SamplingParams
llm = LLM( model="meta-llama/Llama-2-70b-hf", gpu_memory_utilization=0.95, # 提高到95% tensor_parallel_size=4 )
|
降低内存使用率(适用于共享GPU环境):
1 2 3 4
| llm = LLM( model="meta-llama/Llama-2-7b-hf", gpu_memory_utilization=0.7, # 降低到70% )
|
命令行方式:
1 2
| vllm serve meta-llama/Llama-2-70b-hf \ --gpu-memory-utilization 0.95
|
实际案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| # 场景1: 单GPU A100 80GB运行70B模型 llm = LLM( model="meta-llama/Llama-2-70b-hf", gpu_memory_utilization=0.95, dtype="bfloat16", # 预期: ~75GB GPU内存使用 )
# 场景2: 多任务GPU(训练+推理) llm = LLM( model="meta-llama/Llama-2-7b-hf", gpu_memory_utilization=0.6, # 为其他任务预留40% max_num_seqs=64, )
|
3.1.2 精确控制KV Cache大小
优化建议
使用 kv_cache_memory_bytes 替代 gpu_memory_utilization 获得更精确的控制:
1 2 3 4 5 6 7 8 9 10
| # 方式1: 指定KV Cache大小(字节) llm = LLM( model="meta-llama/Llama-2-70b-hf", kv_cache_memory_bytes=40 * 1024**3, # 40GB for KV Cache tensor_parallel_size=4 )
# 方式2: 命令行 vllm serve meta-llama/Llama-2-70b-hf \ --kv-cache-memory-bytes 42949672960 # 40GB
|
计算KV Cache大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| """ KV Cache大小估算公式: KV_cache_size = num_layers * 2 * num_blocks * block_size * num_kv_heads * head_dim * dtype_size
示例: Llama-2-70B - num_layers: 80 - num_kv_heads: 8 - head_dim: 128 - block_size: 16 - dtype: bfloat16 (2 bytes)
单个block大小 = 80 * 2 * 16 * 8 * 128 * 2 bytes = 5,242,880 bytes ≈ 5MB 如果分配40GB: num_blocks = 40 * 1024 / 5 = 8192 blocks """
def estimate_kv_cache_size( num_layers: int, num_kv_heads: int, head_dim: int, block_size: int, dtype_size: int, # 2 for bfloat16/fp16, 1 for fp8 num_blocks: int ) -> int: """计算KV Cache总大小(字节)""" bytes_per_block = num_layers * 2 * block_size * num_kv_heads * head_dim * dtype_size return bytes_per_block * num_blocks
# 示例 kv_cache_gb = estimate_kv_cache_size( num_layers=80, num_kv_heads=8, head_dim=128, block_size=16, dtype_size=2, num_blocks=8192 ) / (1024**3)
print(f"KV Cache size: {kv_cache_gb:.2f} GB")
|
3.1.3 使用量化减少内存占用
FP8量化(推荐用于H100)
1 2 3 4 5 6 7 8
| llm = LLM( model="meta-llama/Llama-2-70b-hf", quantization="fp8", kv_cache_dtype="fp8", # KV Cache也使用FP8 gpu_memory_utilization=0.95 ) # 内存节省: ~50% (相比FP16) # 性能影响: H100上几乎无损,甚至可能更快
|
命令行:
1 2 3
| vllm serve meta-llama/Llama-2-70b-hf \ --quantization fp8 \ --kv-cache-dtype fp8
|
GPTQ/AWQ量化(适用于较旧GPU)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| # GPTQ 4-bit llm = LLM( model="TheBloke/Llama-2-70B-GPTQ", quantization="gptq", dtype="float16" ) # 内存节省: ~75% (相比FP16) # 性能影响: 轻微精度损失,推理速度可能略慢
# AWQ 4-bit llm = LLM( model="TheBloke/Llama-2-70B-AWQ", quantization="awq", dtype="float16" ) # 内存节省: ~75% # 性能影响: AWQ通常比GPTQ精度更高
|
量化对比表
| 量化方法 |
内存节省 |
精度 |
速度 |
适用GPU |
| FP16/BF16 |
基准 |
100% |
基准 |
All |
| FP8 |
~50% |
99%+ |
快10-20% |
H100/A100 |
| AWQ 4-bit |
~75% |
95-98% |
慢0-10% |
All |
| GPTQ 4-bit |
~75% |
93-96% |
慢5-15% |
All |
3.1.4 CPU Offload(超大模型)
使用场景
GPU内存不足以加载完整模型时,将部分权重offload到CPU。
1 2 3 4 5 6
| llm = LLM( model="meta-llama/Llama-2-70b-hf", cpu_offload_gb=20, # 将20GB权重offload到CPU gpu_memory_utilization=0.95 ) # 权衡: 增加延迟,但可以运行更大模型
|
注意事项:
- 需要快速CPU-GPU互连(PCIe 4.0/5.0)
- 显著增加延迟(每次forward需要CPU→GPU传输)
- 建议仅在GPU内存严重不足时使用
3.1.5 KV Cache Offloading(长上下文)
配置示例
1 2 3 4 5 6
| llm = LLM( model="meta-llama/Llama-2-70b-hf", kv_offloading_size=50.0, # 50GB KV offload buffer kv_offloading_backend="native", # 或 "lmcache" tensor_parallel_size=4 )
|
命令行:
1 2 3
| vllm serve meta-llama/Llama-2-70b-hf \ --kv-offloading-size 50.0 \ --kv-offloading-backend native
|
适用场景:
- 长上下文推理(>32K tokens)
- 多轮对话历史保存
- GPU内存有限但CPU内存充足
3.2. 吞吐量优化
3.2.1 增大Batch Size
核心原理
更大的batch size可以更好地利用GPU并行计算能力。
1 2 3 4 5 6
| llm = LLM( model="meta-llama/Llama-2-70b-hf", max_num_seqs=256, # 默认256,可根据GPU内存调整 max_num_batched_tokens=8192, # 增加token budget tensor_parallel_size=4 )
|
根据GPU调整
A100 80GB配置:
1 2 3 4
| vllm serve meta-llama/Llama-2-70b-hf \ --tensor-parallel-size 4 \ --max-num-seqs 256 \ --max-num-batched-tokens 16384
|
A100 40GB配置:
1 2 3 4
| vllm serve meta-llama/Llama-2-70b-hf \ --tensor-parallel-size 4 \ --max-num-seqs 128 \ --max-num-batched-tokens 8192
|
H100配置(利用更大带宽):
1 2 3 4 5
| vllm serve meta-llama/Llama-2-70b-hf \ --tensor-parallel-size 4 \ --max-num-seqs 512 \ --max-num-batched-tokens 32768 \ --kv-cache-dtype fp8 # 充分利用H100的FP8加速
|
3.2.2 启用Chunked Prefill
原理
将长prompt拆分成多个chunk,避免单个超长prefill阻塞所有decode请求。
1 2 3 4 5 6 7 8 9
| from vllm.config import SchedulerConfig
llm = LLM( model="meta-llama/Llama-2-70b-hf", # 启用chunked prefill enable_chunked_prefill=True, max_num_batched_tokens=8192, max_num_seqs=256 )
|
命令行:
1 2 3
| vllm serve meta-llama/Llama-2-70b-hf \ --enable-chunked-prefill \ --max-num-batched-tokens 8192
|
参数调优
1 2 3 4 5 6 7 8 9 10 11
| # 细粒度控制 from vllm import EngineArgs
engine_args = EngineArgs( model="meta-llama/Llama-2-70b-hf", enable_chunked_prefill=True, max_num_batched_tokens=8192, # 每个prefill chunk的最大token数 # 默认值 = max_num_batched_tokens # 可以设置为更小值以提高公平性 )
|
效果:
- 吞吐量提升: 10-30%(长prompt场景)
- 延迟改善: P99延迟降低50%+
3.2.3 前缀缓存(Prefix Caching)
使用场景
- 批量推理时共享相同system prompt
- 多轮对话复用历史上下文
- RAG应用复用文档上下文
1 2 3 4 5
| llm = LLM( model="meta-llama/Llama-2-70b-hf", enable_prefix_caching=True, # V1默认启用 block_size=16, # 前缀缓存粒度 )
|
实际案例
案例1: 批量数据标注
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| # 相同system prompt system_prompt = "你是一个专业的数据标注助手。请按照以下格式标注..."
prompts = [ system_prompt + "\n文本1: ...", system_prompt + "\n文本2: ...", # ... 1000个prompt ]
outputs = llm.generate(prompts, sampling_params)
# 效果: # - 第1个请求: 完整prefill (2s) # - 后续请求: 仅prefill新增部分 (0.2s) # - 总体prefill时间减少: 85%+
|
案例2: 多轮对话
1 2 3 4 5 6 7 8
| # Round 1 prompt1 = "请介绍一下量子计算" output1 = llm.generate(prompt1)
# Round 2 - 复用Round 1的KV Cache prompt2 = prompt1 + output1[0].outputs[0].text + "\n它有哪些应用?" output2 = llm.generate(prompt2) # Prefill时间: 2s → 0.3s (减少85%)
|
监控缓存命中率
1 2 3 4 5 6 7 8 9
| # 启用统计 llm = LLM( model="...", enable_prefix_caching=True, disable_log_stats=False # 启用统计 )
# 查看日志 # INFO: Prefix cache hit rate: 87.3%
|
3.2.4 连续批处理优化
自动启用
vLLM默认使用连续批处理,无需额外配置。
调度策略选择
1 2 3 4 5
| # FCFS (先来先服务) - 默认 vllm serve model --scheduling-policy fcfs
# Priority (优先级调度) vllm serve model --scheduling-policy priority
|
Priority调度示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| # 高优先级请求 sampling_params_high = SamplingParams(temperature=0.7) llm.generate( prompts_high, sampling_params=sampling_params_high, priority=[10] * len(prompts_high) # 高优先级 )
# 低优先级请求 llm.generate( prompts_low, sampling_params=sampling_params_low, priority=[1] * len(prompts_low) # 低优先级 )
|
3.2.5 使用CUDA Graph
默认行为
vLLM V1默认启用CUDA Graph(适用于固定batch size)。
禁用场景
1 2 3 4 5
| llm = LLM( model="...", enforce_eager=True # 禁用CUDA Graph,使用Eager模式 ) # 适用于: batch size高度动态的场景
|
CUDA Graph配置
1 2 3 4 5 6 7 8
| from vllm import EngineArgs
engine_args = EngineArgs( model="meta-llama/Llama-2-70b-hf", enforce_eager=False, # 启用CUDA Graph # 自定义CUDA Graph capture sizes # 默认: [1, 2, 4, 8, 16, 24, 32, 40, 48, 56, 64, ...] )
|
环境变量控制:
1 2 3 4
| # 减少CUDA Graph capture sizes以节省内存 export VLLM_CUDAGRAPH_CAPTURE_SIZES="1,2,4,8,16,32,64,128"
vllm serve meta-llama/Llama-2-70b-hf
|
3.3 延迟优化
3.3.1 减小Batch Size
权衡
更小的batch size可以降低单个请求的排队时间。
1 2 3 4 5
| llm = LLM( model="meta-llama/Llama-2-70b-hf", max_num_seqs=32, # 降低到32(默认256) tensor_parallel_size=4 )
|
吞吐量 vs 延迟对比:
| max_num_seqs |
吞吐量 (tokens/s) |
P50延迟 (ms) |
P99延迟 (ms) |
| 16 |
8,000 |
50 |
150 |
| 64 |
15,000 |
80 |
300 |
| 256 |
25,000 |
120 |
800 |
3.3.2 优先级调度
1 2
| vllm serve meta-llama/Llama-2-70b-hf \ --scheduling-policy priority
|
API使用:
1 2 3 4 5 6 7 8 9 10 11 12 13
| # 紧急请求 outputs_urgent = llm.generate( urgent_prompts, sampling_params=SamplingParams(temperature=0.7), priority=[100] * len(urgent_prompts) )
# 普通请求 outputs_normal = llm.generate( normal_prompts, sampling_params=SamplingParams(temperature=0.7), priority=[50] * len(normal_prompts) )
|
3.3.3 Chunked Prefill调优
1 2 3 4 5 6
| llm = LLM( model="meta-llama/Llama-2-70b-hf", enable_chunked_prefill=True, max_num_batched_tokens=4096, # 降低chunk size # 每个prefill chunk约512 tokens (4096 / 8) )
|
效果:
- TTFT (Time To First Token): 降低30-50%
- P99 latency: 降低40-60%
3.3.4 Speculative Decoding(推测解码)
原理
使用小模型快速生成候选tokens,大模型并行验证。
1 2 3 4 5 6
| llm = LLM( model="meta-llama/Llama-2-70b-hf", # Target model speculative_model="meta-llama/Llama-2-7b-hf", # Draft model num_speculative_tokens=5, # 每次生成5个候选 tensor_parallel_size=4 )
|
命令行:
1 2 3 4
| vllm serve meta-llama/Llama-2-70b-hf \ --speculative-model meta-llama/Llama-2-7b-hf \ --num-speculative-tokens 5 \ --tensor-parallel-size 4
|
性能提升:
- 加速比: 1.5x - 3x(取决于draft model质量)
- 输出完全一致(无精度损失)
- 内存开销: +draft model大小
3.3.5 Tensor Parallelism优化
选择合适的TP大小
单机推理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| # TP=1: 小模型(7B) vllm serve meta-llama/Llama-2-7b-hf
# TP=2: 中等模型(13B-30B) vllm serve meta-llama/Llama-2-13b-hf \ --tensor-parallel-size 2
# TP=4: 大模型(70B) vllm serve meta-llama/Llama-2-70b-hf \ --tensor-parallel-size 4
# TP=8: 超大模型(175B+) vllm serve meta-llama/Llama-2-175b-hf \ --tensor-parallel-size 8
|
原则:
- 尽量减小TP大小(减少通信开销)
- 确保每个GPU有足够内存
- NVLink连接优于PCIe
4. 多GPU优化
4.1 Tensor Parallelism配置
最佳实践
1 2 3 4 5 6 7
| # 单节点8xA100 (NVLink) vllm serve meta-llama/Llama-2-70b-hf \ --tensor-parallel-size 4 \ --gpu-memory-utilization 0.95
# 检查NVLink状态 nvidia-smi topo -m
|
自定义AllReduce
1 2 3 4 5
| llm = LLM( model="meta-llama/Llama-2-70b-hf", tensor_parallel_size=4, disable_custom_all_reduce=False, # 使用优化版AllReduce )
|
环境变量:
1 2 3 4 5
| # 强制使用自定义AllReduce export VLLM_USE_RAY_COMPILED_DAG=1
vllm serve meta-llama/Llama-2-70b-hf \ --tensor-parallel-size 4
|
4.2 Pipeline Parallelism
使用场景
跨节点部署大模型。
1 2 3 4 5 6 7 8
| # 2节点,每节点4GPU (TP=4, PP=2) ray start --head --node-ip-address=192.168.1.100 ray start --address=192.168.1.100:6379
vllm serve meta-llama/Llama-2-70b-hf \ --tensor-parallel-size 4 \ --pipeline-parallel-size 2 \ --distributed-executor-backend ray
|
Pipeline调优
1 2 3 4 5 6 7
| llm = LLM( model="meta-llama/Llama-2-70b-hf", tensor_parallel_size=4, pipeline_parallel_size=2, # 批处理队列大小(减少pipeline bubble) # V1自动优化,无需手动设置 )
|
4.3 Data Parallelism
配置示例
使用Ray:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| # 启动2个独立engine实例 import ray from vllm import LLM
ray.init()
@ray.remote(num_gpus=4) class LLMWorker: def __init__(self): self.llm = LLM( model="meta-llama/Llama-2-70b-hf", tensor_parallel_size=4 ) def generate(self, prompts): return self.llm.generate(prompts)
# 创建2个worker(8 GPUs total) workers = [LLMWorker.remote() for _ in range(2)]
# 负载均衡 results = ray.get([ workers[i % 2].generate.remote(batch) for i, batch in enumerate(batches) ])
|
使用外部负载均衡器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| # Node 1 vllm serve meta-llama/Llama-2-70b-hf \ --host 0.0.0.0 --port 8000 \ --tensor-parallel-size 4
# Node 2 vllm serve meta-llama/Llama-2-70b-hf \ --host 0.0.0.0 --port 8000 \ --tensor-parallel-size 4
# Nginx配置 upstream vllm_backend { server 192.168.1.100:8000; server 192.168.1.101:8000; }
|
4.4 混合并行策略
场景1: 单节点8xH100
1 2 3 4 5 6
| # 策略1: TP=8 (最大化单节点性能) vllm serve meta-llama/Llama-2-70b-hf \ --tensor-parallel-size 8
# 策略2: TP=4, DP=2 (平衡延迟和吞吐量) # 需要外部启动2个实例或使用Ray
|
场景2: 4节点 x 8GPU
1 2 3 4 5
| # 策略: TP=8, PP=4 (跨节点大模型) vllm serve meta-llama/Llama-2-400b-hf \ --tensor-parallel-size 8 \ --pipeline-parallel-size 4 \ --distributed-executor-backend ray
|
5. CUDA优化
5.1 CUDA Graph
自动优化
vLLM V1自动使用CUDA Graph,无需手动配置。
查看CUDA Graph状态
1 2
| # 查看日志 # INFO: Captured 32 CUDA graphs
|
自定义Capture Sizes
1 2 3 4
| # 环境变量方式 export VLLM_CUDAGRAPH_CAPTURE_SIZES="1,2,4,8,16,32,64,128,256"
vllm serve meta-llama/Llama-2-70b-hf
|
CUDA Graph模式配置(V1新特性)
vLLM V1支持多种CUDA Graph模式,提供不同的性能权衡。
CUDA Graph模式说明:
| 模式 |
描述 |
适用场景 |
性能特点 |
| NONE |
不使用CUDA Graph |
调试、不支持的后端 |
最灵活,性能最低 |
| PIECEWISE |
分段CUDA Graph |
通用场景 |
平衡性能和灵活性 |
| FULL |
完整CUDA Graph |
小模型、固定batch |
最高性能,最低延迟 |
| FULL_DECODE_ONLY |
仅decode用完整图 |
Prefill/Decode分离 |
Decode高性能,节省内存 |
| FULL_AND_PIECEWISE |
混合模式(默认) |
通用高性能场景 |
推荐,最佳综合性能 |
1. FULL模式(完整CUDA Graph)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| from vllm import LLM from vllm.config import CompilationConfig, CUDAGraphMode
# 方式1:Python API llm = LLM( model="meta-llama/Llama-2-7b-hf", compilation_config=CompilationConfig( cudagraph_mode=CUDAGraphMode.FULL, # 完整CUDA Graph ), max_num_seqs=64, gpu_memory_utilization=0.90, )
# 方式2:使用字符串 llm = LLM( model="meta-llama/Llama-2-7b-hf", compilation_config=CompilationConfig( cudagraph_mode="FULL", # 字符串形式 ), )
|
命令行配置:
1 2
| vllm serve meta-llama/Llama-2-7b-hf \ --compilation-config '{"cudagraph_mode": "FULL"}'
|
FULL模式特点:
性能对比:
| 配置 |
TTFT (ms) |
TPOT (ms) |
吞吐量 |
启动时间 |
| NONE |
基准 |
基准 |
基准 |
最快 |
| PIECEWISE |
-15% |
-10% |
+10% |
快 |
| FULL |
-30% |
-20% |
+15% |
慢 |
| FULL_AND_PIECEWISE |
-25% |
-15% |
+20% |
最慢(推荐) |
2. FULL_AND_PIECEWISE模式(推荐,V1默认)
这是V1的默认模式,提供最佳综合性能。
1 2 3 4 5 6 7 8 9 10 11
| from vllm import LLM from vllm.config import CompilationConfig, CUDAGraphMode
llm = LLM( model="meta-llama/Llama-2-70b-hf", compilation_config=CompilationConfig( cudagraph_mode=CUDAGraphMode.FULL_AND_PIECEWISE, # V1默认 ), tensor_parallel_size=4, max_num_seqs=128, )
|
工作原理:
- Decode批次:使用完整CUDA Graph(最高性能)
- Prefill批次:使用分段CUDA Graph(灵活性)
- 混合批次:使用分段CUDA Graph
优势:
- 自动选择最佳策略
- Decode阶段获得最高性能(最常见操作)
- Prefill阶段保持灵活性
- 适用于99%的生产场景
3. FULL_DECODE_ONLY模式(P/D分离优化)
适用于Prefill/Decode分离架构。
1 2 3 4 5 6 7 8 9 10 11
| from vllm import LLM from vllm.config import CompilationConfig, CUDAGraphMode
# Decode实例配置 llm_decode = LLM( model="meta-llama/Llama-2-70b-hf", compilation_config=CompilationConfig( cudagraph_mode=CUDAGraphMode.FULL_DECODE_ONLY, ), tensor_parallel_size=4, )
|
命令行:
1 2 3 4
| # Decode实例 vllm serve meta-llama/Llama-2-70b-hf \ --compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' \ --tensor-parallel-size 4
|
特点:
- 仅Decode批次使用完整CUDA Graph
- 混合批次不使用CUDA Graph
- 节省内存(不为混合批次捕获图)
- 适合P/D分离架构中的Decode实例
4. PIECEWISE模式(传统模式)
1 2 3 4 5 6
| llm = LLM( model="meta-llama/Llama-2-70b-hf", compilation_config=CompilationConfig( cudagraph_mode=CUDAGraphMode.PIECEWISE, ), )
|
特点:
- Attention等操作不在CUDA Graph内
- 最大灵活性
- 适用于不支持cudagraph的attention后端
5. 完整配置示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| from vllm import LLM from vllm.config import CompilationConfig, CUDAGraphMode
# 高性能生产配置(推荐) llm = LLM( model="meta-llama/Llama-2-70b-hf", # CUDA Graph配置 compilation_config=CompilationConfig( cudagraph_mode=CUDAGraphMode.FULL_AND_PIECEWISE, # 混合模式 cudagraph_capture_sizes=[1, 2, 4, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128], max_cudagraph_capture_size=128, # 最大捕获大小 cudagraph_num_of_warmups=3, # 预热次数 # 编译模式 mode=3, # VLLM_COMPILE模式 backend="inductor", # 使用Inductor后端 ), # 其他配置 tensor_parallel_size=4, max_num_seqs=128, gpu_memory_utilization=0.92, )
|
6. 环境变量配置
1 2 3 4 5 6 7 8 9 10
| # 自定义CUDA Graph捕获大小 export VLLM_CUDAGRAPH_CAPTURE_SIZES="1,2,4,8,16,32,64,128,256"
# 启动服务 vllm serve meta-llama/Llama-2-70b-hf \ --compilation-config '{ "cudagraph_mode": "FULL_AND_PIECEWISE", "mode": 3, "backend": "inductor" }'
|
7. 模式选择指南
| 场景 |
推荐模式 |
原因 |
| 通用生产环境 |
FULL_AND_PIECEWISE |
最佳综合性能 |
| 小模型(<13B) |
FULL |
内存充足,追求极致性能 |
| P/D分离-Decode |
FULL_DECODE_ONLY |
优化decode,节省内存 |
| P/D分离-Prefill |
PIECEWISE 或 NONE |
Prefill灵活性更重要 |
| 调试/开发 |
NONE |
最大灵活性 |
| 不支持cudagraph的后端 |
PIECEWISE 或 NONE |
兼容性 |
| 内存紧张 |
PIECEWISE |
减少图捕获内存 |
8. 注意事项
FULL模式限制:
- 需要FlashAttention-2或其他支持cudagraph的attention后端
- FlashInfer backend某些配置下不支持
- Triton attention不支持
内存影响:
1 2 3 4 5 6
| # FULL模式会为每个batch size捕获图 # 如果cudagraph_capture_sizes很长,会占用大量内存 compilation_config=CompilationConfig( cudagraph_mode=CUDAGraphMode.FULL, max_cudagraph_capture_size=64, # 限制最大size减少内存 )
|
启动时间:
1 2 3
| # FULL模式启动时间更长(需要捕获更多图) # 在生产环境中,启动时间通常可以接受 # 可以通过减少capture sizes加速启动
|
9. 性能调优技巧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| # 技巧1:精简capture sizes compilation_config=CompilationConfig( cudagraph_mode=CUDAGraphMode.FULL_AND_PIECEWISE, # 只捕获常用的batch sizes cudagraph_capture_sizes=[1, 2, 4, 8, 16, 32, 64], # 少量sizes max_cudagraph_capture_size=64, )
# 技巧2:增加预热次数(更稳定的性能) compilation_config=CompilationConfig( cudagraph_mode=CUDAGraphMode.FULL, cudagraph_num_of_warmups=5, # 默认0,增加到5 )
# 技巧3:LoRA适配器优化 compilation_config=CompilationConfig( cudagraph_mode=CUDAGraphMode.FULL_AND_PIECEWISE, cudagraph_specialize_lora=True, # 为LoRA创建专门的图 )
|
10. 监控CUDA Graph效果
1 2 3 4 5 6 7 8 9 10 11
| # 启用详细日志 export VLLM_LOGGING_LEVEL=DEBUG
vllm serve meta-llama/Llama-2-7b-hf \ --compilation-config '{"cudagraph_mode": "FULL"}'
# 查看日志输出 # DEBUG: Capturing CUDA graph for batch size 1 # DEBUG: Capturing CUDA graph for batch size 2 # ... # INFO: Captured 32 CUDA graphs in 45.2s
|
5.2 编译优化
Torch Compile
1 2 3 4 5 6 7 8 9 10 11 12 13
| from vllm import LLM from vllm.config import CompilationConfig
llm = LLM( model="meta-llama/Llama-2-70b-hf", compilation_config=CompilationConfig( level=3, # 编译级别: 0-3 # level 0: 禁用 # level 1: 基础优化 # level 2: 中等优化 # level 3: 激进优化(推荐) ) )
|
命令行:
1 2
| vllm serve meta-llama/Llama-2-70b-hf \ --compilation-level 3
|
预编译Cache
1 2 3 4 5 6
| # 设置编译缓存目录 export VLLM_XLA_CACHE_PATH=/path/to/cache
vllm serve meta-llama/Llama-2-70b-hf # 首次运行: 编译并缓存 # 后续运行: 直接加载缓存,启动更快
|
5.3 Kernel优化
FlashAttention版本
1 2 3 4 5 6 7
| # 自动选择最佳FlashAttention版本 # V1: 默认使用FlashAttention-2
# 强制使用特定版本(调试用) export VLLM_FLASH_ATTN_VERSION=2
vllm serve meta-llama/Llama-2-70b-hf
|
禁用特定Kernel(调试)
1 2 3 4
| # 禁用某些kernel(用于兼容性调试) export VLLM_DISABLED_KERNELS="flash_attn,paged_attn"
vllm serve meta-llama/Llama-2-70b-hf
|
5.4 FP8优化(H100)
全面启用FP8
1 2 3 4 5 6
| llm = LLM( model="meta-llama/Llama-2-70b-hf", quantization="fp8", kv_cache_dtype="fp8", dtype="bfloat16", # 保持激活为BF16 )
|
性能提升:
- 吞吐量: +50% (H100)
- 延迟: -20%
- 内存: -50%
FP8动态量化
1 2 3 4 5
| # 启用动态FP8量化 export VLLM_FP8_DYNAMIC_QUANT=1
vllm serve meta-llama/Llama-2-70b-hf \ --quantization fp8
|
6. 缓存优化
6.1 前缀缓存调优
Block Size选择
1 2 3 4 5 6 7
| llm = LLM( model="meta-llama/Llama-2-70b-hf", enable_prefix_caching=True, block_size=16, # 默认16 # block_size越大: 缓存粒度越粗,内存效率越高 # block_size越小: 缓存粒度越细,命中率越高 )
|
推荐配置:
- 短prompt (<512 tokens):
block_size=8
- 中等prompt (512-2048):
block_size=16
- 长prompt (>2048):
block_size=32
Hash算法选择
1 2 3 4 5 6
| llm = LLM( model="meta-llama/Llama-2-70b-hf", enable_prefix_caching=True, # 选项: "sha256", "sha256_cbor" # sha256_cbor: 更稳定,跨语言兼容 )
|
6.2 多模态缓存
图像/视频缓存
1 2 3 4 5
| llm = LLM( model="llava-hf/llava-1.5-7b-hf", # 多模态输入缓存大小(GB) mm_input_cache_gib=4, # 默认4GB )
|
命令行:
1 2 3
| export VLLM_MM_INPUT_CACHE_GIB=8 # 增加到8GB
vllm serve llava-hf/llava-1.5-7b-hf
|
6.3 Encoder缓存
适用模型
编码器-解码器模型(如BART, T5)或多模态模型。
1 2 3 4 5
| # 自动管理encoder cache llm = LLM( model="t5-large", # encoder cache由scheduler自动管理 )
|
7. 模型特定优化
7.1 Llama系列
Llama-2 70B优化配置
1 2 3 4 5 6 7 8 9
| vllm serve meta-llama/Llama-2-70b-hf \ --tensor-parallel-size 4 \ --dtype bfloat16 \ --gpu-memory-utilization 0.95 \ --enable-prefix-caching \ --enable-chunked-prefill \ --max-num-batched-tokens 16384 \ --max-num-seqs 256 \ --block-size 16
|
Llama-3.1 405B优化配置
1 2 3 4 5 6 7 8 9
| # 需要8xH100或16xA100 vllm serve meta-llama/Meta-Llama-3.1-405B \ --tensor-parallel-size 8 \ --pipeline-parallel-size 2 \ --dtype bfloat16 \ --quantization fp8 \ --kv-cache-dtype fp8 \ --gpu-memory-utilization 0.95 \ --distributed-executor-backend ray
|
7.2 Mixtral MoE
优化配置
1 2 3 4 5 6
| vllm serve mistralai/Mixtral-8x7B-v0.1 \ --tensor-parallel-size 2 \ --dtype bfloat16 \ --gpu-memory-utilization 0.9 \ --enable-prefix-caching \ --max-num-seqs 128
|
MoE特定优化:
1 2 3 4
| # 调整MoE chunk size export VLLM_FUSED_MOE_CHUNK_SIZE=65536
vllm serve mistralai/Mixtral-8x7B-v0.1
|
7.3 DeepSeek-V3
FP8优化
1 2 3 4 5 6
| vllm serve deepseek-ai/DeepSeek-V3 \ --tensor-parallel-size 8 \ --dtype bfloat16 \ --kv-cache-dtype fp8 \ # DeepSeek-V3默认FP8 --gpu-memory-utilization 0.95 \ --enable-chunked-prefill
|
7.4 多模态模型(LLaVA)
优化配置
1 2 3 4 5 6 7 8 9
| llm = LLM( model="llava-hf/llava-1.5-13b-hf", dtype="bfloat16", mm_input_cache_gib=8, # 增加图像缓存 mm_processor_kwargs={ "num_crops": 4 # 图像分块数 }, gpu_memory_utilization=0.9 )
|
8. 部署架构优化
8.1 Prefill/Decode分离
架构设计
1 2 3 4 5 6 7 8 9 10
| ┌──────────────────┐ │ Prefill Cluster │ (H100, 高算力) │ - 生成KV Cache │ └────────┬─────────┘ ↓ KV Transfer ┌────────────────────┐ │ Decode Cluster │ (A100 80GB, 大显存) │ - 接收KV Cache │ │ - 执行Decode │ └────────────────────┘
|
Prefill实例配置
1 2 3 4 5 6
| vllm serve meta-llama/Llama-2-70b-hf \ --tensor-parallel-size 8 \ --gpu-memory-utilization 0.9 \ --kv-connector LMCacheConnector \ --kv-role kv_producer \ --host 0.0.0.0 --port 8000
|
Decode实例配置
1 2 3 4 5 6
| vllm serve meta-llama/Llama-2-70b-hf \ --tensor-parallel-size 8 \ --gpu-memory-utilization 0.95 \ --kv-connector LMCacheConnector \ --kv-role kv_consumer \ --host 0.0.0.0 --port 8001
|
收益:
- 资源利用率提升: 30-50%
- Prefill使用高算力GPU (H100)
- Decode使用大显存GPU (A100 80GB)
8.2 负载均衡部署
Nginx配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| upstream vllm_backend { least_conn; # 最少连接数负载均衡 server 192.168.1.100:8000 max_fails=3 fail_timeout=30s; server 192.168.1.101:8000 max_fails=3 fail_timeout=30s; server 192.168.1.102:8000 max_fails=3 fail_timeout=30s; }
server { listen 80; location /v1/completions { proxy_pass http://vllm_backend; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_buffering off; proxy_read_timeout 300s; } }
|
8.3 自动扩展(Kubernetes)
HPA配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: vllm-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: vllm-deployment minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: gpu-utilization target: type: Utilization averageUtilization: 80 - type: Pods pods: metric: name: requests_per_second target: type: AverageValue averageValue: "100"
|
9. 监控与调优
9.1 启用Prometheus Metrics
1 2 3 4
| vllm serve meta-llama/Llama-2-70b-hf \ --disable-log-stats \ # 禁用默认日志 --enable-prometheus # 启用Prometheus # Metrics端点: http://localhost:8000/metrics
|
9.2 关键指标
吞吐量指标
1 2
| vllm:avg_prompt_throughput_tps # Prefill吞吐量 (tokens/s) vllm:avg_generation_throughput_tps # Decode吞吐量 (tokens/s)
|
延迟指标
1 2 3
| vllm:time_to_first_token_seconds # TTFT vllm:time_per_output_token_seconds # TPOT vllm:e2e_request_latency_seconds # 端到端延迟
|
资源利用率
1 2 3
| vllm:gpu_cache_usage_perc # KV Cache使用率 vllm:num_requests_running # 正在执行的请求数 vllm:num_requests_waiting # 等待队列长度
|
9.3 Grafana Dashboard
样例查询
吞吐量监控:
1
| rate(vllm:avg_generation_throughput_tps[5m])
|
P99延迟:
1 2 3
| histogram_quantile(0.99, rate(vllm:e2e_request_latency_seconds_bucket[5m]) )
|
KV Cache使用率:
1
| avg(vllm:gpu_cache_usage_perc)
|
9.4 性能分析
Torch Profiler
1 2 3 4 5 6 7
| # 启用Torch Profiler export VLLM_TORCH_PROFILER_DIR=/path/to/traces export VLLM_TORCH_PROFILER_WITH_STACK=1
vllm serve meta-llama/Llama-2-70b-hf
# 使用Chrome查看: chrome://tracing
|
CUDA Profiler
1 2 3 4 5 6 7
| # Nsight Systems nsys profile -o vllm_profile \ python -m vllm.entrypoints.openai.api_server \ --model meta-llama/Llama-2-70b-hf
# 分析 nsys-ui vllm_profile.nsys-rep
|
10. 常见问题与解决方案
10.1 OOM (Out Of Memory)
问题
GPU内存不足导致进程崩溃。
解决方案
方案1: 降低GPU内存使用率
1
| vllm serve model --gpu-memory-utilization 0.8
|
方案2: 减小batch size
1
| vllm serve model --max-num-seqs 64 --max-num-batched-tokens 4096
|
方案3: 使用量化
1
| vllm serve model --quantization fp8 --kv-cache-dtype fp8
|
方案4: 增加TP
1
| vllm serve model --tensor-parallel-size 4
|
10.2 低吞吐量
问题
实际吞吐量远低于预期。
诊断
1 2 3 4 5 6 7 8 9
| # 检查指标 # 1. GPU利用率 nvidia-smi
# 2. KV Cache使用率 # 查看日志: vllm:gpu_cache_usage_perc
# 3. Batch size # 查看日志: num_requests_running
|
解决方案
方案1: 增加batch size
1
| vllm serve model --max-num-seqs 256 --max-num-batched-tokens 16384
|
方案2: 启用前缀缓存
1
| vllm serve model --enable-prefix-caching
|
方案3: 使用CUDA Graph
1 2
| # 确保enforce_eager=False (默认) vllm serve model
|
10.3 高延迟
问题
P99延迟过高。
解决方案
方案1: 启用Chunked Prefill
1
| vllm serve model --enable-chunked-prefill
|
方案2: 减小batch size
1
| vllm serve model --max-num-seqs 32
|
方案3: 优先级调度
1
| vllm serve model --scheduling-policy priority
|
10.4 CUDA Graph相关错误
错误信息
1
| RuntimeError: CUDA error: an illegal memory access was encountered
|
解决方案
1 2
| # 禁用CUDA Graph vllm serve model --enforce-eager
|
10.5 分布式通信慢
问题
多GPU场景下AllReduce通信慢。
诊断
1 2 3 4
| # 检查NVLink nvidia-smi topo -m
# 期望看到NVLink连接,而非PCIe
|
解决方案
方案1: 使用NVLink GPU
方案2: 启用自定义AllReduce
1 2 3
| vllm serve model \ --tensor-parallel-size 4 \ --disable-custom-all-reduce=False
|
方案3: 减小TP大小
1 2
| # 从TP=8降到TP=4 vllm serve model --tensor-parallel-size 4
|
11. 最佳实践总结
11.1 通用推荐配置
高吞吐量场景(批量推理)
1 2 3 4 5 6 7 8
| vllm serve meta-llama/Llama-2-70b-hf \ --tensor-parallel-size 4 \ --gpu-memory-utilization 0.95 \ --max-num-seqs 256 \ --max-num-batched-tokens 16384 \ --enable-prefix-caching \ --enable-chunked-prefill \ --dtype bfloat16
|
低延迟场景(在线服务)
1 2 3 4 5 6 7 8
| vllm serve meta-llama/Llama-2-70b-hf \ --tensor-parallel-size 4 \ --gpu-memory-utilization 0.9 \ --max-num-seqs 64 \ --max-num-batched-tokens 8192 \ --scheduling-policy priority \ --enable-chunked-prefill \ --dtype bfloat16
|
平衡配置
1 2 3 4 5 6 7 8
| vllm serve meta-llama/Llama-2-70b-hf \ --tensor-parallel-size 4 \ --gpu-memory-utilization 0.92 \ --max-num-seqs 128 \ --max-num-batched-tokens 12288 \ --enable-prefix-caching \ --enable-chunked-prefill \ --dtype bfloat16
|
11.2 硬件特定优化
H100优化
1 2 3 4 5 6
| vllm serve meta-llama/Llama-2-70b-hf \ --tensor-parallel-size 4 \ --quantization fp8 \ --kv-cache-dtype fp8 \ --gpu-memory-utilization 0.95 \ --max-num-batched-tokens 32768
|
A100优化
1 2 3 4 5
| vllm serve meta-llama/Llama-2-70b-hf \ --tensor-parallel-size 4 \ --dtype bfloat16 \ --gpu-memory-utilization 0.92 \ --max-num-batched-tokens 16384
|
A100 40GB优化(内存受限)
1 2 3 4 5 6 7
| vllm serve meta-llama/Llama-2-70b-hf \ --tensor-parallel-size 4 \ --dtype bfloat16 \ --gpu-memory-utilization 0.88 \ --max-num-seqs 128 \ --max-num-batched-tokens 8192 \ --kv-cache-dtype fp8 # 使用FP8压缩KV
|
11.3 调优流程
Step 1: 基准测试
1 2 3 4 5
| # 使用默认配置 vllm bench throughput \ --model meta-llama/Llama-2-70b-hf \ --input-len 512 --output-len 128 \ --num-prompts 1000
|
Step 2: 内存优化
1 2
| # 调整gpu_memory_utilization # 监控nvidia-smi,确保不OOM
|
Step 3: Batch优化
1 2
| # 逐步增加max_num_seqs和max_num_batched_tokens # 直到吞吐量不再增加或出现OOM
|
Step 4: 启用高级特性
1 2
| # 启用prefix caching, chunked prefill等 # 测量性能提升
|
Step 5: 微调
本文来自[常平]vLLM V1性能优化指南