vLLM推理框架与传统推理方式的性能差异
大模型推理部署中,KV Cache内存管理是核心瓶颈。传统推理框架(如Hugging Face Transformers)为每个请求预分配连续的KV Cache内存块,当请求长度变化时造成大量内存碎片,实际GPU显存利用率通常不到40%。vLLM通过PagedAttention机制将KV Cache按固定大小的块(block)进行管理,类似操作系统的虚拟内存分页,显存利用率可提升至90%以上。
vLLM的另一项关键技术是连续批处理(Continuous Batching)。传统静态批处理需要等待同一批次所有请求生成完毕才能释放资源,长尾请求拖慢整体吞吐量。连续批处理在每个生成步骤动态加入新请求、移除已完成请求,GPU始终满载运行,吞吐量提升2-4倍。
vLLM安装与模型加载配置
vLLM支持从Hugging Face Hub或本地路径加载模型。安装依赖后即可启动推理服务:
pip install vllm
启动OpenAI兼容的API服务器:
from vllm import LLM, SamplingParams
# 加载模型,指定GPU张量并行度
llm = LLM(
model="Qwen/Qwen2.5-7B-Instruct",
tensor_parallel_size=1, # GPU数量
dtype="float16", # 半精度推理
gpu_memory_utilization=0.90, # 显存占用上限
max_model_len=8192, # 最大上下文长度
enforce_eager=False, # 启用CUDA Graph加速
swap_space=4, # CPU swap空间(GB)
)
gpu_memory_utilization控制vLLM可使用的显存比例。设置为0.90表示vLLM会预留90%的GPU显存用于KV Cache,剩余10%留给模型权重和其他开销。在多模型共存的GPU上需要调低此值。
enforce_eager=False启用CUDA Graph优化,将推理计算图预编译为GPU原生执行流,减少每次推理的内核启动开销。对于固定batch size的推理场景,CUDA Graph可额外提升15-20%的推理速度。
PagedAttention内存管理原理
PagedAttention将每个序列的KV Cache分割为固定大小的block(默认每block存储16个token的KV)。每个序列维护一个block table,记录其KV Cache在物理显存中的块映射关系。这种设计带来三个优势:
第一,消除内存碎片。不同长度序列的KV Cache占用不同数量的block,block之间无需连续,GPU显存中的空闲block可被任意序列使用。
第二,支持Copy-on-Write。在beam search或并行采样(一个prompt生成多个输出)场景中,多个输出共享同一prompt的KV Cache,仅在token分叉时复制对应block,大幅减少内存重复占用。
第三,支持Prefix Caching。对于相同system prompt或few-shot prefix的请求,vLLM会缓存prefix的KV Cache blocks,新请求命中缓存时直接复用,减少prefill计算量。在多轮对话场景中,前几轮的KV Cache可直接复用,响应延迟降低50%以上。
# 启用prefix caching
llm = LLM(
model="Qwen/Qwen2.5-7B-Instruct",
enable_prefix_caching=True, # 开启前缀缓存
max_num_seqs=256, # 最大并发序列数
max_num_batched_tokens=16384, # 单批次最大token数
)
连续批处理调度器配置
vLLM的调度器(Scheduler)在每个生成步骤执行以下操作:检查已完成序列并移出batch;检查waiting队列中是否有新请求可加入;根据剩余显存block数量决定加入多少新请求。调度策略分为两个队列:
# 核心调度参数
llm = LLM(
model="Qwen/Qwen2.5-7B-Instruct",
max_num_seqs=256, # batch中最大序列数
max_num_batched_tokens=16384, # 单步最大token数(prefill阶段)
preemption_mode="swap", # 显存不足时的抢占策略
)
max_num_seqs限制同时处理的序列数。设置为256意味着GPU上最多同时有256个请求在生成。数值过大会导致显存压力,触发频繁的swap操作降低性能;过小则无法充分利用GPU并行能力。
preemption_mode设置显存不足时的处理策略。swap将低优先级序列的KV Cache换出到CPU内存,释放GPU显存给新请求;recompute则直接丢弃低优先级序列的KV Cache,需要时重新计算。swap模式适合内存充足但有波动的场景,recompute模式适合内存极度紧张的场景。
量化推理部署与性能对比
大模型量化推理可将显存占用减少50-75%,在同等GPU上部署更大参数模型。vLLM原生支持AWQ、GPTQ和INT8量化模型:
# 加载AWQ量化模型
llm = LLM(
model="TheBloke/Llama-3-8B-Instruct-AWQ",
quantization="awq",
dtype="float16",
gpu_memory_utilization=0.85,
)
# 加载GPTQ量化模型
llm = LLM(
model="TheBloke/Llama-3-8B-Instruct-GPTQ",
quantization="gptq",
dtype="float16",
)
# INT8量化(需安装bitsandbytes)
llm = LLM(
model="meta-llama/Llama-3-8B-Instruct",
quantization="bitsandbytes",
load_format="bitsandbytes",
dtype="float16",
)
量化推理的性能对比参考(以Llama-3-8B为例,单卡A100 80GB):
- FP16:吞吐量约3500 tokens/s,显存占用16GB,精度损失<0.5%
- AWQ-4bit:吞吐量约5200 tokens/s,显存占用6GB,精度损失约1-2%
- GPTQ-4bit:吞吐量约4800 tokens/s,显存占用6GB,精度损失约1-2%
- INT8:吞吐量约4100 tokens/s,显存占用9GB,精度损失约0.5-1%
AWQ在4bit量化方案中推理速度最快,精度损失可控,是目前vLLM部署中推荐的量化方案。GPTQ的兼容性更广,社区量化模型资源丰富。实际选型需在推理速度、精度和模型可用性之间权衡。
多GPU张量并行与服务化部署
单GPU显存不足以加载大参数模型时,使用张量并行将模型权重切分到多张GPU上。vLLM通过NCCL实现GPU间通信,对用户透明:
# 双卡张量并行
llm = LLM(
model="Qwen/Qwen2.5-72B-Instruct",
tensor_parallel_size=2, # 2卡张量并行
dtype="float16",
gpu_memory_utilization=0.90,
max_model_len=32768,
)
# 使用vLLM server启动API服务
# vllm serve Qwen/Qwen2.5-72B-Instruct \
# --tensor-parallel-size 2 \
# --gpu-memory-utilization 0.90 \
# --max-model-len 32768 \
# --port 8000
启动API服务后,通过OpenAI兼容接口调用:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="vllm")
response = client.chat.completions.create(
model="Qwen/Qwen2.5-72B-Instruct",
messages=[{"role": "user", "content": "解释PagedAttention的工作原理"}],
max_tokens=2048,
temperature=0.7,
stream=True, # 流式输出
)
生产部署中需配合Nginx或Envoy做负载均衡,多vLLM实例之间通过Round-Robin或最少连接数策略分发请求。每个实例独立管理自己的KV Cache和调度器,通过水平扩展提升整体吞吐量。监控指标重点关注gpu_cache_usage_perc(显存利用率)、num_requests_running(运行中请求数)和time_to_first_token(首token延迟),作为扩容和参数调优的依据。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/da-mo-xing-tui-li-jia-su-shi-zhan-vllmpagedattention-nei/