vLLM
目前最主流的大模型推理部署框架 vLLM,核心创新是 PagedAttention,借鉴操作系统虚拟内存分页思想管理 KV Cache。
PagedAttention:把 KV Cache 切成固定大小的“页”,按需分配,彻底消除显存碎片,并发请求共享 KV Cache 成为可能。Continuous Batching(连续批处理):不等一批请求全部完成再处理下一批,而是动态插入新请求,GPU 利用率从 30% 提升到 90%+。Prefix Caching:相同前缀(如 System Prompt)的 KV Cache 自动复用,多轮对话场景首 token 延迟大幅降低。Speculative Decoding(投机采样):用小模型草稿 + 大模型验证,在不损失精度的前提下提升生成速度。支持 OpenAI 兼容 API,一行命令启动,已成为企业私有化部署的事实标准。
介绍
vLLM(Vectorized Large Language Model Serving System)是加州大学伯克利分校团队推出的开源推理系统,突破大模型部署中显存利用率低与推理吞吐量受限的双重挑战
Meta 前 PyTorch 团队推出 vLLM,最大特色“PagedAttention”。
两项核心机制:PagedAttention(分页注意力)与Continuous Batching(连续批处理),二者均受操作系统内存分页机制启发,重构了注意力计算与请求调度的底层逻辑,从而在不牺牲精度的前提下,大幅优化了显存管理效率与并发推理能力。
- PagedAttention:受操作系统分页管理机制启发,将注意力机制中的键值缓存(KV Cache)以非连续方式部署于显存中。相较传统框架为每个请求强制分配连续显存块的模式,vLLM 将 KV Cache 拆分为固定尺寸的“页”,实现显存空间的动态调度与高效复用,从而彻底缓解了显存碎片化、预留冗余与并发容量受限三大核心痛点。该架构使显存利用率由传统方案的 60% 显著跃升至 95% 以上,显著增强系统对高并发请求的承载能力。
- PagedAttention:KV 缓存被划分为块;块在内存空间中不需要连续
- Continuous Batching:突破传统批量等待机制,支持新请求实时插入处理队列,实现GPU资源的零空闲运行。该机制显著降低高并发场景下的TTFT(首字出词时间),在Llama3.1-170B-FP8单H100环境下,TTFT低至123ms,优于TensorRT-LLM(194ms)与SGLang(340ms)。
多卡并行优化:全面兼容张量并行(Tensor Parallelism)与流水线并行(Pipeline Parallelism),依托NCCL/MPI等高性能通信框架,实现模型参数的精细化切分与高效同步,在降低显存占用的同时,显著增强整体吞吐能力。
量化优化支持:原生集成GPTQ、AWQ等先进量化算法,精准压缩模型参数规模,大幅提升GPU计算密度与推理效率,实现性能与资源消耗的最优平衡。
【2025-12-13】DeepSeek倒逼vLLM升级!芯片内卷、MoE横扫千模,vLLM核心维护者独家回应:如何凭PyTorch坐稳推理“铁王座”
2023 年, 加州大学伯克利分校 Sky Computing Lab 学生与研究员开源核心的 PagedAttention 技术,vLLM
短短一年多, GitHub Star 数突破 4 万,并迅速增长至如今的 6.5 万,如今已成为全球科技公司首选的推理引擎。
2024 年 11 月,红帽正式收购 Neural Magic,并将包括 vLLM 核心维护者 Michael Goin 在内的核心团队纳入旗下。
vLLM(Very Large Language Model)专为大语言模型(LLM)优化的高效推理框架
其核心:PagedAttention、动态批处理pd并行、多LoRA动态加载等
PagedAttention 本质是灵活管理 KV Cache(注意力缓存)的方式。
- 传统 transformer 推理时,每个 token 都带上历史上下文,缓存爆炸。
- vLLM 通过类似虚拟内存分页方式,优化性能。像会打麻将的高效服务员,记牌记得巨快
好处
- API 设计接近 OpenAI 标准接口,部署友好,尤其对做“OpenAI替代”的场景特别合适。
- 高并发时不掉链子,响应速度几乎线性增长。
前提:GPU A100 起步。
vllm vs sglang
【2025-09-27】vllm:pd并行、多LoRA动态加载
vllm和sglang 部署分别:
- vLLM 在高并发和低延迟场景下表现优异,尤其擅长快速生成第一个词(TTFT低)。
- SGLang 在多轮对话这类前缀复用率高的场景中,吞吐量优势明显,测试显示其在Llama-7B上的吞吐量可比vLLM高5倍。
问题
vllm 默认占满显存
【2026-3-26】案例
- vllm 加载 qwen-7b 模型,显存占到40G左右,但关掉vllm时占用17G
- vllm 加载 qwen3-4b 模型,A6000,显存占41G!
显存计算公式:
- 显存占用 ≈ KV Cache + 模型参数 + 激活值 + 临时buffer
$ [ \text{显存占用} \approx \text{KV Cache} + \text{模型参数} + \text{激活值} + \text{临时 buffer}] $
详见站内专题:GPU显存分析
gpu_memory_utilization 默认值为 0.9,GPU 内存的使用率为 90%。如果遇到显存不足的问题,可以降低该值。
- KV 缓存:在自回归解码过程中,LLM 的所有输入标记会生成注意键和值张量,并保存在 GPU 内存中,这些缓存可能会占用大量显存。
- vLLM 引入 PagedAttention 来有效管理 KV 缓存,这种机制允许在不连续内存空间中存储连续的键和值。
通过合理调整 gpu_memory_utilization 参数,可以在保证模型性能的同时,优化显存的使用。
调用代码
import vllm
model = vllm.LLM(
model_path="/data/models/Meta-Llama-3-8B-Instruct",
tensor_parallel_size=2,
gpu_memory_utilization=0.15, # 设置显存利用率为 15%
temperature=0.2,
top_p=0.95,
max_tokens=100
)
vllm 不支持 embedding的lora
【2025-2-4】vllm 不支持 embedding的lora功能!
It’s not supported yet according to the compatibility matrix. Let me update the supported models page to avoid this confusion. cc @jeejeelee
undefined symbol
【2026-4-7】错误信息
import vllm._C # noqa
^^^^^^^^^^^^^^
ImportError: /ofs/ese-llm-ssd/users/wangqiwen/envs/py312/lib/python3.12/site-packages/vllm/_C.abi3.so: undefined symbol: _ZN3c104cuda29c10_cuda_check_implementationEiPKcS2_ib
分析
- 豆包:vllm 与 PyTorch/CUDA 版本不兼容
解法
- 查看 pytorch、cuda和vllm版本
- 对照 vllm 官方要求(关键):
- vllm 0.4.x+ 需 PyTorch ≥ 2.0.0,CUDA ≥ 11.8
- vllm 0.3.x 需 PyTorch ≥ 1.13.0,CUDA ≥ 11.7
- 升级对应版本
# 查看当前 PyTorch 版本:
python -c "import torch; print(torch.__version__); print(torch.version.cuda)"
# 查看当前 vllm 版本:
uv pip list | grep vllm
# 升级vllm: 0.16 -> 0.19
uv pip install vllm --upgrade
vLLM 框架
核心架构是LLMEngine:包含调度器(Scheduler)和推理工作器(Worker)
- 调度器(Scheduler):
- 调度策略(policy):
- 请求的连续批处理(Continuous Batching)
- 请求队列维护:waiting(待处理)、running(正在处理)、swapped(因显存不足被挂起)
- 空间“调度指挥官”(BlockSpaceManager):负责逻辑资源规划与分配策略;
- 计算kv cache需要的块数量
- 判断是否需要为新token分配新的空间(如需则通知cacheengine)
- 内存共享:例如在并行采样时,多个输出序列可共享同一prompt的KV缓存块
- 调度策略(policy):
- 推理工作器(Worker):
- 模型运行:包括多GPU分布式计算(张量并行、流水线并行)
- 空间“后勤执行者”(CacheEngine):负责物理显存的具体操作与数据存取。
- 性能效果:
- 吞吐:提升高达24倍
- 耗时:提升1.2倍。
多 LoRA 动态加载
- 无延迟切换:单基础模型(如Llama 3-8B)同时挂载多个LoRA适配器(如聊天/函数调用),请求时通过lora_request参数指定,切换延迟低于1ms。
- 资源复用:基础模型参数仅加载一次,适配器共享显存,支持5+适配器并行服务。
与stable diffusion类似,vllm 也支持在请求调用时指定调用某个lora;但有两点差异:
- vllm中的lora是一开始全部就加载进模型的,(sd是请求时才加载)
- vllm中每次请求只能指定一个lora
# 同时加载两个适配器
vllm serve meta-llama/Meta-Llama-3-8B \
--enable-lora \
--lora-modules \
oasst=/path/to/oasst_adapter \ # 名称 oasst
xlam=/path/to/xlam_adapter # 名称 xlam
PagedAttention 动态分页机制
分页注意力机制(PagedAttention)是什么?
- 分页注意力机制借鉴了计算机操作系统中的内存分页管理,通过动态分配和复用显存空间,显著提升大模型推理的效率和吞吐量。
传统大模型推理中,注意力机制(Transformer的自注意力层)为每个请求序列分配连续的显存块,存储以下数据:
- (1)键值缓存(Key-Value Cache,KV Cache):存储历史token的键值对,用于生成后续token。
- (2)中间激活值:计算注意力权重时的中间结果。
vLLM基于PyTorch构建,创新性地引入了PagedAttention技术。借鉴操作系统的虚拟内存分页机制,将注意力键值对(KV Cache)存储在非连续显存空间,显著提高了显存利用率。
PagedAttention 通过分块管理显存、动态按需分配和跨请求共享内存,解决了传统方法中显存碎片化、预留浪费和并发限制三大瓶颈。
特点
- 分块管理KV缓存:将注意力键值(Key-Value Cache)划分为固定大小的块(如4-16 tokens/块),按需动态分配GPU显存,避免传统连续分配导致的碎片问题。
- 显存复用与共享:短序列推理时仅占用必要块,释放空间供其他请求使用;支持跨请求的缓存共享(如相同前缀提示词),显存利用率提升最高达25%。
- 写时复制(Copy-on-Write):共享块标记为只读,修改时创建新副本,减少重复计算
vllm 部署
安装
# 安装基础版本
pip install vllm
# 安装支持CUDA的版本
# pip install vllm-nightly # 无效,报错
pip install -U vllm \
--torch-backend=auto \
--extra-index-url https://wheels.vllm.ai/nightly
vllm 两种模型部署方式:
- 在线服务形式(Online Serving)
- 在线服务: 通过指令启动vllm服务,将模型以服务的形式完成部署,之后可以通过openai格式的api来访问模型
- 离线推理形式 (Offline Inference)
- 离线推理: 通过类方式初始化一个模型,之后传入提示词即可访问模型
vllm 使用
# 示例代码:生成文本
from vllm import LLM, SamplingParams
prompts = ["什么是vLLM?", "vLLM的优势是什么?"]
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)
llm = LLM(model="meta-llama/Llama-2-7b-chat-hf") # 可限制最大并发:max_num_seqs=2,使用FP16:dtype="float16"
outputs = llm.generate(prompts, sampling_params) # 批量推理
for output in outputs:
print(f"输入:{output.prompt}\n输出:{output.outputs[0].text}\n"2
服务开启和各参数作用
vllm 服务启动指令如下
vllm serve deepseek-ai/deepseek-vl2-tiny \
--hf_overrides '{"architectures": ["DeepseekVLV2ForCausalLM"]}' \
--dtype float16 --trust_remote_code \
--host 0.0.0.0 --port 8080 \
--chat_template template_deepseek_vl2.jinja \
--gpu-memory-utilization 0.7 \
--limit-mm-per-prompt "image=8"
详见地址
bert 模型
除了生成式任务,但分类任务同样可以通过指定合适的任务类型实现。
【2025-5-1】vLLM项目中部署BERT
关键启动参数包括:
python -m vllm.entrypoints.api_server \
--model path/to/bert_model \
--tensor-parallel-size 1 \
--dtype float16 \
--max-model-len 512 \
--served-model-name bert-cls
注意:
- 最大序列长度应设置为BERT标准配置(通常512)
- 半精度(float16)可显著提升推理速度
- 服务名称用于后续API调用标识
分类任务可以采用以下调用方式:
import openai
client = openai.Client(base_url="http://localhost:8000/v1")
response = client.completions.create(
model="bert-cls",
prompt="这是一条需要分类的文本",
max_tokens=1, # 分类任务通常只需要1个token输出
temperature=0 # 确保确定性输出
)
性能优化建议
- 批处理优化:通过增大
--max-batch-size参数提高吞吐量 - 量化部署:尝试使用
--quantization bitsandbytes进行8bit量化 - 请求合并:客户端实现请求队列合并,减少小包传输
- 监控集成:添加Prometheus监控指标采集
vLLM 分布式
资料
- 【2025-09-07】利用 vLLM 进行 rollout
- 【2025-11-30】vLLM & Ray 分布式部署Qwen2.5-14B模型
- 【2025-12-17】vLLM MoE 调优手册(上篇):TP、DP、PP 与 Expert Parallelism 实战指南
更多分布式计算知识,见站内专题:分布式训练理论
vLLM 并行方式
vLLM 并行方式:
- Tensor Parallelism(TP,张量并行):每个gpu只存权重的1/n, 计算完成后都要AllReduce同步
- Data Parallelism(DP,数据并行)
- Pipeline Parallelism(PP,流水线并行)
- Expert Parallelism(EP,专家并行,MoE 专用开关)
vLLM 允许设置 PP 和 DP
问题:
- TP 如何切分权重、为何需要 AllReduce
- DP+EP 在 MoE 场景下如何配合 AllToAll 做请求级并行
- 为什么所谓的“DP Attention” 和传统数据并行完全不是一回事
- 什么时候要开
--enable-expert-parallel,什么时候反而是徒增开销
「交叉点」:
- TP+EP:低并发、交互式场景下延迟更优
- DP+EP:高并发、大吞吐场景下扩展性更好
专家激活密度(每个 token 实际激活多少 expert)会直接决定 EP 是加速还是减速;而像 DeepSeek 这种 MLA/MQA 模型,在 KV cache 管理上又需要特别对待。
DP
命令
vllm serve model-name --data-parallel-size 4
TP
vllm 部署 Qwen 2.5 14B 模型
下载模型
huggingface-cli download Qwen/Qwen2.5-14B –resume-download –local-dir /data/models/qwen2.5-14b
查看模型的参数:
cat /data/models/qwen2.5-14b/config.json
vllm 部署模型时要设置 tensor-parallel-size 和 pipeline-parallel-size 两个参数,和模型结构、GPU设备数量都有关系
- 参数涉及到模型并行的两种方式 Tensor Parallelism (TP,
张量并行)和Pipeline Parallelism (PP,流水线并行)
只采用 Tensor Parallelism,不采用 Pipeline Parallelism。
从config.json中 可以知道注意力头的数量 “num_attention_heads”是 40
- num_attention_heads 必须是 tensor-parallel-size 张量并行度的整数倍。
vllm 部署命令:
vllm serve model-name --tensor-parallel-size 4
关闭 NCCL,使用 ray
export NCCL_IB_DISABLE=1
export NCCL_SOCKET_IFNAME=eth0
export NCCL_DEBUG=INFO
python -m vllm.entrypoints.openai.api_server \
--model /data/models/qwen2.5-14b \
--tensor-parallel-size 4 \
--pipeline-parallel-size 1 \
--trust-remote-code \
--gpu-memory-utilization 0.75 \
--max-num-seqs 64 \
--max-model-len 4096 \
--host 0.0.0.0 \
--port 8000 \
--distributed-executor-backend=ray
测试验证
另起终端界面,运行以下命令,测试模型是否可用
curl http://localhost:8000/v1/completions \
-H "Content-Type: application/json" \
-d '{"model": "/data/models/qwen2.5-14b","max_tokens":"256" ,"temperature": "0.7","prompt": "请介绍一下你自己?"}' | jq
PP
把模型的不同层拆给不同 GPU / 节点,每块 GPU 负责一段「流水线阶段」,数据像装配线一样一级一级往后传
vLLM 不会傻傻地让流水线一次只跑一个请求,而是同时塞进多条请求:
- GPU 0 处理请求 B 的第 1 段
- GPU 1 同时处理请求 A 的第 2 段
- GPU 2 可能在处理更早一条请求的第 3 段
这样流水线各阶段都能被填满,大幅减少 pipeline bubble。
示例
# Pure PP: 4 GPUs as 4 pipeline stages
vllm serve model-name --pipeline-parallel-size 4
# TP within nodes + PP across nodes (2 pipeline stages with each pipeline has 4 GPUs)
vllm serve model-name --tensor-parallel-size 4 --pipeline-parallel-size 2
或
llm = LLM(
model=str(model_dir),
dtype='bfloat16',
gpu_memory_utilization=0.4,
tensor_parallel_size=2, # 张量并行
pipeline_parallel_size = 2, # 流水线并行
data_parallel_size = 2
)
TP 和 PP 很好理解,而DP 的意思应该是,例如你有4张卡,设置 TP = 2 , PP = 1 ,此时 vLLM 内部会启动“两份模型”, 进行并行的数据处理
MoE
部署 DeepSeek-R1 这类超大 Mixture-of-Experts(MoE)模型时,问题不只是“有多少块 GPU”,而是这些 GPU 怎么配合工作。
- 选错并行策略→ KV cache 被复制 8 倍、显存直接爆掉,或者通信开销占了一半时间、吞吐被腰斩。
- 选对并行策略→ 同样硬件上,针对业务场景,性能明显提升。
Expert Parallelism(EP,专家并行)是专为 MoE 模型设计的“修饰开关“,需要和 TP 或 DP 组合使用
概念:Sharded Experts vs Split Experts
| 维度 | Sharded Experts | Split Experts |
|---|---|---|
| 定义 | 每块GPU持有全部专家,单个专家的权重张量在多GPU间分片存储 | 专家整体分发至不同GPU,每块GPU仅持有部分完整专家 |
| 使用 | 不开 –enable-expert-parallel | 开启 –enable-expert-parallel |
| 示例 (256个专家,TP=8) |
每块GPU均有256个专家,单个专家权重仅存1/8 | TP=8+EP, 每块GPU仅存32个完整专家(GPU0:0-31、GPU1:32-63…) |
| 并行组合 | 仅搭配张量并行(TP) | 可搭配张量并行(TP)+专家并行(EP),还可结合数据并行(DP) |
| 通信方式 | 通过AllReduce聚合分片计算结果 | 1. 与DP结合:用AllToAll完成token与专家路由 2. 仅与TP结合:用AllReduce |
| 存储特点 | 单专家权重分片,无完整专家独占GPU | 单GPU存储完整专家,专家整体分布式部署 |
EP 开关控制什么?
- 不开 EP:每块 GPU 上都有全部专家,权重张量被切片(shard),使用AllReduce 聚合;
- 开EP:专家在 GPU 之间做分布(split),当 DP > 1 时:使用 AllToAll(DP Attention);当DP = 1、只有 TP 时:仍然是 AllReduce。
MoE 并行常见误区
- 误区1:“Expert Parallelism 是一种单独的并行方式” ———— 不是,而是开关
--enable-expert-parallel,改写 MoE 层通信与映射方式,只能和 TP 或 DP 搭配使用- 注意:只有当 TP_SIZE × DP_SIZE > 1 时,EP 才会真正生效,否则会被直接忽略
- 误区2:“DP Attention 就是普通的数据并行” ———— MoE 模型上,vLLM 用特殊的 “DP Attention”,和 Data Parallelism 完全不同。
- 误区3:“所有 experts 在 MoE 中都是一样的”———— 不对,MoE 模型中两类 expert行为截然不同。
- 误区4:“TP+EP 通信和 DP+EP 一样都是 AllToAll” ———— TP+EP 只用 AllReduce,完全不会走 AllToAll。vLLM 源码中,AllToAll kernel 的启用条件是:dp_size > 1
DP vs DP Attention
名词区分
传统 DP(Data Parallelism)
- 每块 GPU(或一个 TP 组)上都有完整一份模型副本
- 各副本处理不同请求,互不通信(推理阶段)
DP Attention
- 仍用
--data-parallel-size N配置,但语义:在一个逻辑「大模型副本」内部做请求级并行 - Attention 层是复制的,而 MoE 层的行为取决于是否开 EP
- 推理过程中需要 AllGather / AllToAll / slice 等操作,在 GPU 间反复重排 batch
- 只能在:
- ■ 搭配 EP:形成「DP + EP」
- ■ 不搭 EP:退化为传统 DP,不再具备 KV cache 分区收益
TP 对 MLA/MQA 的问题
Multi-Latent Attention(MLA)与 Multi-Query Attention(MQA)只有一个 KV 头:
- TP 可以按 head 维把 Q/K/V 的线性层切片
- 但KV cache 只有一个 head,没法再按head 维度切
结果:
- KV cache 在所有 TP rank 上完整复制
例子:TP=32 时:
- 线性层计算:每块 GPU 只算 1/32 的 head ✅
- KV cache:每块 GPU 都有 完整副本❌
- 显存浪费极其严重
DP Attention 不再是「多个独立模型副本」,而是一个逻辑模型内部的分工:
- 每块 GPU 上都有完整的非 MoE 层(attention、dense)
- 但 KV cache 按请求 / token 维度切分:
- 每块 GPU 只存自己负责那一部分请求的 KV cache
- 推理时通过 AllToAll 在 GPU 之间互相转发 token
对比传统 DP:
- 传统 DP:每块 GPU 处理自己的 batch,KV cache 完整复制在每个副本中
- DP Attention:一个「逻辑 batch」被拆散,KV cache 被分布到多个 GPU
示例:TP=4,DP=8(共 32 块 GPU)
- 32 块 GPU = 8 个 DP 组 × 每组 4 块 GPU 做 TP
- 非 MoE 计算:每块 GPU 算 1/4 的 head(组内 TP)
- KV cache:每个 DP 组只持有自己请求的 KV,组内 4 块再细分
- AllReduce:只在每个 4-GPU TP 组内做,不跨 32 块全局
- 不同 DP 组之间处理的是完全不同的一批请求
可用性
- MoE + DP Attention 在 vLLM v0.9.0+ 的 V1 engine 中可用,
- 是为 DeepSeek-V2/V3/R1 这类 MLA/MQA 架构专门设计的。
MoE Expert 种类
MoE 模型中通常有两类 expert,行为截然不同。
Routed Experts
- 通过路由机制按需激活
- 每个token 只会激活一小部分 expert(例如 256 中激活 8 个)
- EP 开启时:通过 determine_expert_map 把 routed expert 分布到不同 GPU
- EP 关闭时:所有 routed expert 在每块 GPU 上都存在,但权重会按 flatten_tp_across_dp做切片
- DeepSeek-R1:有 256 个 routed experts
Shared Experts
- 每个 token 都会激活(没有路由)
- 更像一层普通的 dense MLP
- 默认情况权重也是切片存储,只有在以下条件同时满足时才会复制
vLLM 源码解析
【2024-4-12】图解大模型计算加速系列:vLLM源码解析2,调度器策略(Scheduler)
- 一、入口函数
- 二、SequenceGroup
- 2.1 原生请求输入
- 2.2 SequenceGroup的作用
- 2.3 SequenceGroup的结构
- 三、add_request: 预处理请求
- 四、step:调度器策略
- 4.1 调度器结构
- 4.2 整体调度流程
- 4.3 _passed_delay:waiting队列调度时间阈值判断
- 4.4 can_allocate:能否为seq_group分配物理块(prefill)
- 4.5 can_append_slot: 能否为seq_group分配物理块(decode)
- 4.6 allocate与append_slot:为seq_group实际分配物理块
- 4.7 preempt:抢占策略
- 4.8 调度器整体代码解读
案例
‘qwen-vllm - 通义千问VLLM推理部署DEMO’
- GitHub: qwen-vllm
支付宝打赏
微信打赏