vLLM轻松通
欢迎来到啾啾的博客🐱。
记录学习点滴。分享工作思考和实用技巧,偶尔也分享一些杂谈💬。
有很多很多不足的地方,欢迎评论交流,感谢您的阅读和评论😄。
目录
- 引言
- 1 vLLM基本概念
- 1.1 PagedAttention
- 1.2 连续批处理
- 1.3 应用场景
- 2 使用vLLM部署LLM为服务
- 2.1 部署方式
- 2.2 运行管理
- 2.3 性能与资源调优(AI搜索)
- 2.4 容器化与扩展
- 2.5 监控
引言
vLLM主要是解决大模型推理服务化问题,专于与推理、优化GPU使用、提供吞吐量,提供简单易用的API接口,支持Hugging Face模型无缝接入。
本篇,让我们一起了解vLLM。
vLLM安装命令,需要安装的很多,请耐心等待。
- 官方文档
https://docs.vllm.ai/en/stable/index.html
pip install vllm
AI使用声明:本文使用了AI进行资料检索,结构优化。
1 vLLM基本概念
vLLM 是一个用于 LLM 推理和服务的快速易用库。核心优势在于极高的推理性能。
详情介绍推荐看官方文档。
这里需要提前说明的是,Windows不支持vLLM,我们需要使用WSL 2进行开发,建议配置一个Windows+WSL 2的混合开发环境。
1.1 PagedAttention
要理解vLLM,首先要理解其核心技术:PagedAttention。传统LLM服务在处理批量请求时,需要为每个请求预先分配一块连续的显存空间来存储注意力机制中的键(Key)和值(Value),即KV Cache。这种方式存在两个主要问题:
- 显存浪费:由于请求的序列长度不同,预留的空间往往远大于实际需要,导致大量内部碎片。
- 吞吐量受限:需要为最长的可能序列分配内存,限制了并发处理的请求数量。
PagedAttention借鉴了操作系统中虚拟内存和分页的思想,将KV Cache存储在非连续的显存块(Block)中。这带来了极大的优势:
- 近乎零的显存浪费:按需分配,显存利用率大幅提升。
- 更高的吞-吐量:显存利用率的提升意味着可以并发处理更多的请求。
- 更灵活的内存管理:可以轻松实现跨请求的KV Cache共享,例如在Beam Search或并行生成多个输出时,极大地优化了复杂采样策略的性能。
1.2 连续批处理
vLLM采用了iterative-level schedule(通常称为continuous batching)的调度算法,能够动态地将不同长度的请求组合成批次进行处理,极大提高了GPU利用率。这一技术使系统能够在处理长文本请求的同时,不浪费计算资源等待新请求的到来。
vLLM吞吐量比HuggingFace Transformers高出24倍,展现出显著的效率优势。相比其他推理框架如FasterTransformer,vLLM更加简单易用,不需要额外进行复杂的模型转换过程,降低了部署门槛。
1.3 应用场景
vLLM适用于多种实际应用场景:
- 实时问答系统:如智能客服机器人、知识库检索系统,能够提供低延迟的响应体验。
- 模型服务化部署:可快速构建大模型后端服务,支持高并发请求处理。
- 对话系统:通过高效的推理引擎,vLLM能够实时响应用户请求,提供流畅的对话体验。
- 内容生成:在文本生成、语言建模、机器翻译、情感分析等多个领域都有广泛应用。
- 教学与实验:由于其在消费级GPU上的良好表现,vLLM也成为教学实验平台的理想选择。
2 使用vLLM部署LLM为服务
2.1 部署方式
1.使用内置API服务器
- 传统方式
vLLM内置了一个兼容OpenAI API的服务器,这也是最推荐的部署方式。
# 启动API服务器,加载你从ModelScope下载的本地模型
python -m vllm.entrypoints.openai.api_server \--model "./qwen_7b_chat/qwen/Qwen1.5-7B-Chat" \--host 0.0.0.0 \--port 8000 \--trust-remote-code \--gpu-memory-utilization 0.90
参数解释如下:
- –model: 指定模型路径,可以是Hugging Face ID或本地路径。
- –host 0.0.0.0: 允许从任何网络接口访问服务。
- –port 8000: 指定服务监听的端口。
- –trust-remote-code: 同样需要。
- –gpu-memory-utilization 0.90: 控制vLLM使用的显存比例,默认0.9。如果GPU上有其他任务,可以适当调低。
- –tensor-parallel-size: 使用的GPU数量
- –max-model-len: 模型最大上下文长度(默认4096)
- –dtype 指定模型权重和计算过程中使用的数据类型
- –quantization: 量化方式(awq/gptq等)
服务启动后,你就可以用任何HTTP客户端(如curl, Python requests)像调用OpenAI API一样调用你的模型了。
比如使用OpenAI兼容的客户端调用:
from openai import OpenAIclient = OpenAI(base_url="http://localhost:8000/v1",api_key="EMPTY" # 无需API密钥
)response = client.chat.completions.create(model="meta-llama/Meta-Llama-3-8B-Instruct",messages=[{"role": "user", "content": "你好,请介绍一下你自己"}],max_tokens=512,temperature=0.7
)print(response.choices[0].message.content)
curl的方式
curl http://localhost:8000/v1/chat/completions \-H "Content-Type: application/json" \-d '{"model": "meta-llama/Meta-Llama-3-8B-Instruct","messages": [{"role": "user", "content": "你好"}],"temperature": 0.7}'
- 新的方式 vllm serve
vLLM ≥ 0.3.0可以用这种方式,兼容所有传统方式的参数。
# 现代方式 (vLLM ≥ 0.3.0)
vllm serve /workspace/models/Qwen/Qwen2.5-1.5B-Instruct \# 基础配置--host 0.0.0.0 \ # 监听所有IP(生产必备)--port 8000 \ # 服务端口--max-model-len 32768 \ # Qwen2.5推荐值# 性能核心参数(阿里云黄金配置)--tensor-parallel-size 1 \ # GPU数量--dtype bfloat16 \ # A100最佳选择--max-num-seqs 256 \ # 吞吐量关键!--max-num-batched-tokens 4096 \ # 配合max-num-seqs--block-size 16 \ # PagedAttention分页# 高级优化(长文本必备)--enable-chunked-prefill \ # 分块预填充--max-paddings 256 \ # 减少填充浪费# 监控与生产特性--served-model-name qwen2.5-1.5b \ # API路由标识--enable-metrics \ # Prometheus监控--metrics-host 0.0.0.0 \ # 阿里云ARMS对接--max-log-len 1024 # 日志截断(防OOM)
2.也可以在Python应用中集成
from vllm import LLM, SamplingParams# 初始化LLM引擎
llm = LLM(model="meta-llama/Meta-Llama-3-8B-Instruct",tensor_parallel_size=1,max_model_len=4096
)# 设置采样参数
sampling_params = SamplingParams(temperature=0.7,top_p=0.95,max_tokens=512
)# 生成文本
outputs = llm.generate(["你好,介绍一下你自己"], sampling_params)# 打印结果
for output in outputs:print(f"生成结果: {output.outputs[0].text}")
3.多模型部署
vllm可以单实例部署多个模型
# 单实例部署多个模型
vllm serve \/models/Qwen/Qwen2.5-1.5B-Instruct --served-model-name qwen-1.5b \/models/Qwen/Qwen2.5-7B-Instruct --served-model-name qwen-7b \--port 8000--tensor-parallel-size $GPUS# 智能识别可用GPU数量
vllm serve /models/Qwen2.5-1.5B-Instruct \--tensor-parallel-size $GPUS
2.2 运行管理
- 启动
vllm serve /workspace/models/Qwen/Qwen2.5-1.5B-Instruct \--host 0.0.0.0 \--port 8000 \--tensor-parallel-size 1 \--max-num-seqs 256 \--max-model-len 32768 \--enable-chunked-prefill
使用 curl http://localhost:8000/v1/models
验证。
启动后使用Ctrl +C或者通过pid停止。
在生产环境中,需要使用systemd服务管理
# 创建服务文件
cat > /etc/systemd/system/vllm.service <<EOF
[Unit]
Description=vLLM Inference Service
After=network.target[Service]
User=root
WorkingDirectory=/workspace
ExecStart=/bin/bash -c "vllm serve /models/Qwen/Qwen2.5-1.5B-Instruct \--host 0.0.0.0 \--port 8000 \--tensor-parallel-size 1 \--max-num-seqs 256"
Restart=always
RestartSec=5
Environment=PYTHONUNBUFFERED=1[Install]
WantedBy=multi-user.target
EOF# 停止服务
systemctl stop vllm.service# 查看状态
systemctl status vllm.service
2.3 性能与资源调优(AI搜索)
vLLM中所有关键性能参数如下:
- 优先级最高的参数
参数 | 作用机制 | 推荐值(7B模型) | 阿里云优化建议 | 性能影响 |
---|---|---|---|---|
--max-num-seqs | 控制同时处理的最大请求数,是连续批处理的核心 | 128-512 | A10实例:256 A100实例:512 | ⚡⚡⚡⚡⚡ (吞吐量±40%) |
--max-num-batched-tokens | 批处理中最大token总数 | 2048-4096 | Qwen模型:4096 长文本场景:8192 | ⚡⚡⚡⚡ (GPU利用率±35%) |
--block-size | PagedAttention内存分页大小 | 8-16 | A100:16 消费卡:8 | ⚡⚡⚡⚡ (显存碎片↓30%) |
- 关键参数
参数 | 作用机制 | 推荐值 | 阿里云场景建议 | 调优技巧 |
---|---|---|---|---|
--gpu-memory-utilization | GPU显存利用率阈值 | 0.9-0.95 | A100:0.95 显存紧张:0.85 | 从0.9逐步提升,监控OOM |
--swap-space | CPU-GPU交换空间大小(GB) | 4-8 | 突发流量:8 稳定服务:4 | 配合--max-num-seqs 使用 |
--enable-chunked-prefill | 分块预填充处理长文本 | true/false | 上下文>4K:必开 | 需设置--max-num-batched-tokens |
--max-model-len | 模型最大上下文长度 | 模型原生值*1.2 | Qwen:32768 Llama3:8192 | 实际设置值应≥业务最大需求 |
- 进阶参数
参数 | 适用场景 | 阿里云最佳实践 |
---|---|---|
--pipeline-parallel-size | 多GPU流水线并行 | 大模型(>30B)必备,与tensor-parallel-size 协同 |
--max-seq-len-to-capture | CUDA Graph优化长度 | A100:8192 避免动态shape |
--quantization | 量化方式 | AWQ:精度损失<1% 显存↓40% |
--served-model-name | 多模型部署别名 | 阿里云API网关路由必备 |
-
张量并行 (–tensor-parallel-size): 当模型太大单张GPU放不下时,可以用此参数将模型切分到多张GPU上。例如 --tensor-parallel-size 4 会使用4张GPU。这是服务大模型(如70B)的必备参数。
-
数据类型 (–dtype): 使用–dtype bfloat16 或 --dtype float16 可以显著降低显存占用,提升推理速度。auto是默认选项。这个参数直接影响推理速度、显存占用、数值精度。
值 | 全称 | 显存占用 | 速度 | 适用场景 | 阿里云GPU建议 |
---|---|---|---|---|---|
auto | 自动选择 | - | ⚡⚡⚡ | 推荐默认值 | 所有场景 |
half | FP16 (float16) | 50% | ⚡⚡⚡ | 通用场景 | A10/A100/V100 |
bfloat16 | Brain Float16 | 50% | ⚡⚡⚡⚡ | 最佳推荐 | A100/AI加速卡 |
float | FP32 (float32) | 100% | ⚡ | 精度敏感任务 | 不推荐生产环境 |
float16 | 同half | 50% | ⚡⚡⚡ | 与half 相同 | 所有场景 |
fp8 | 实验性FP8 | 25% | ⚡⚡⚡⚡ | 预览版 | A100/H100 |
- 最大模型长度 (–max-model-len): 限制模型能处理的最大序列长度(上下文+生成)。这个值会影响KV Cache的显存预留,需要根据你的业务场景和硬件资源来权衡。
2.4 容器化与扩展
LLM部署的最佳实践是将vLLM服务容器化,这也是云原生的基础。。
-
Docker: 强烈建议将你的vLLM服务打包成Docker镜像。这可以固化所有环境依赖(CUDA, Python库等),保证在任何地方都能一致地运行。vLLM官方也提供了Dockerfile作为参考。
-
Kubernetes (K8s): 在大规模生产环境中,使用K8s来管理你的Docker容器。K8s可以为你提供:
- 自动扩缩容: 根据请求量自动增加或减少运行vLLM的Pod数量。
- 健康检查与自愈: 如果某个vLLM实例崩溃,K8s会自动重启它。
- 负载均衡: 将流量均匀分发到所有健康的vLLM实例上。
2.5 监控
vLLM通过/metrics端点暴露了Prometheus格式的监控指标。我们需要将这些指标接入监控系统(如Prometheus + Grafana),并重点关注:
- vllm_running_requests: 当前正在处理的请求数。
- vllm_avg_prompt_throughput_toks_per_s: Prompt处理吞吐量。
- vllm_avg_generation_throughput_toks_per_s: 生成吞吐量。
- vllm_gpu_cache_usage_perc: KV Cache的显存使用率。