即使在昂贵的GPU硬件上,大语言模型服务仍然可能慢得惊人。主要瓶颈在于KV缓存管理低效和批处理策略不合理:
vLLM是来自加州大学伯克利分校的开源项目,核心贡献是PagedAttention算法,重新定义了LLM推理服务,比HuggingFace Transformers吞吐量高出高达24倍,且不需要任何模型架构修改。
PagedAttention的灵感来自操作系统中的虚拟内存和分页机制。
与传统注意力算法要求KV缓存连续存储不同,PagedAttention允许连续的Key和Value存储在不连续的内存空间中。
具体来说:
PagedAttention中,只有序列最后一个块会有浪费,实际上内存浪费率低于4%,接近最优。
内存效率提高允许系统将更多序列一起批处理,大幅提高GPU利用率和吞吐量。
PagedAttention另一个关键优势是高效的内存共享:
传统静态批处理 vs vLLM连续批处理:
| 传统静态批处理 | vLLM连续批处理 |
|---|---|
| 必须等batch内所有序列都生成完才能下一批 | 每次迭代完成后,如果有空闲容量,立即加入新请求 |
| 短序列要等长序列,GPU资源浪费 | 动态调整batch,充分利用GPU |
| 延迟高,吞吐量低 | 延迟更低,吞吐量更高 |
1from vllm import LLM, SamplingParams
2
3prompts = [
4 "Hello, my name is",
5 "The president of the United States is",
6 "The capital of France is",
7 "The future of AI is",
8]
9
10sampling_params = SamplingParams(temperature=0.8, top_p=0.95)
11llm = LLM(model="facebook/opt-125m")
12outputs = llm.generate(prompts, sampling_params)
13
14for output in outputs:
15 prompt = output.prompt
16 generated_text = output.outputs[0].text
17 print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")1python -m vllm.entrypoints.openai.api_server \
2 --model lmsys/vicuna-7b-v1.3 \
3 --port 8000客户端调用:
1import openai
2openai.api_key = "EMPTY"
3openai.api_base = "http://localhost:8000/v1"
4
5completion = openai.Completion.create(
6 model="lmsys/vicuna-7b-v1.3",
7 prompt="San Francisco is a"
8)1from vllm import LLM
2# 4 GPU张量并行
3llm = LLM("facebook/opt-13b", tensor_parallel_size=4)
4output = llm.generate("San Franciso is a")优点:
缺点:
在ShareGPT数据集上的吞吐量对比:
| 模型 | HF Transformers | TGI | vLLM |
|---|---|---|---|
| LLaMA-7B (A10G) | 1x | 1x | 24x (HF), 3.5x (TGI) |
| LLaMA-13B (A100) | 1x | 1x | 8.5-15x (HF), 3.3-3.5x (TGI) |
A: 灵感来自操作系统的虚拟内存分页。解决的是LLM推理中KV缓存内存碎片化和利用率低的问题,传统方法浪费60%-80%内存,PagedAttention把浪费降到4%以下,大幅提高吞吐量。
A: 将KV缓存分成固定大小的块,块可以不连续存储,通过块表映射。只有每个序列最后一个块会浪费,平均浪费率低于4%。
A: Continuous Batching是vLLM的迭代级调度机制,每次迭代完成后,如果GPU还有容量,就立即加入新请求,不需要等整个batch所有序列完成。传统批处理必须等所有完成才能下一批,短序列要等长序列,GPU利用率低。Continuous Batching提高了GPU利用率,增加了吞吐量,降低了延迟。
A: 并行采样时多个输出序列共享同一个prompt的KV缓存,通过块表映射实现。用引用计数跟踪物理块,当多个引用都要修改时用Copy-on-Write复制副本,保证安全。共享可以把内存占用降低高达55%。
A: 主要两个原因:1) PagedAttention大幅提高内存利用率,可以同时批处理更多序列,GPU更高利用率;2) Continuous Batching动态调度,减少GPU空闲等待,提高吞吐量。
A: 自定义模型集成复杂,早期版本对LoRA等适配器支持有限,大模型并发下相比LightLLM还有提升空间。