大模型推理机制与压测实战:从 Transformer 到 vLLM/TGI/LMDeploy 全解析
本文基于实际压测数据与框架源码分析,系统梳理了大模型推理的核心机制(Transformer、注意力、因果掩码、KV-cache、PagedAttention 等),并对比主流推理框架(vLLM、TGI、LMDeploy)的底层实现与性能表现,适合用于技术分享、面试准备与工程选型。
一、Transformer 结构回顾

Inputs=源句
Output(shiffed right) = 目标句
Output Probabilities = 可能的下一个词
1.1 数据处理
Transformer 的输入处理是:文本 → token-id → embedding → +位置编码 → 正式进入模型。
1.分词 → 映射为 token-id
组件:Tokenizer(AutoTokenizer)
2.查表 → 得到 token embedding
组件:nn.Embedding(权重就是模型文件里的 token_embedding.weight)
1.2 编码器(Encoder)图中左边部分
- 一次性并行处理整个源句的嵌入向量,生成每个 token 的 K/V 表示。
- 提供给 Decoder 用于交叉注意力,用完即弃。
- 每个 token 的 K/V 包含整句信息,因此 BERT 等纯 Encoder 模型可见全文。
1.3 解码器(Decoder)图中右边部分
- 自回归生成,每步生成一个新 token,一边随时回头查这些k/v向量,注意力权重动态决定“该看哪”。
- Decoder 自己的自注意力 K/V 也是每步重新算的,为了记录以生产内容,保证自回归。
- 使用因果掩码(Causal Mask)保证只能看左边。
- 交叉注意力使用 Encoder 提供的 K/V,Q 来自 Decoder 自身。
注:交叉注意力即Decoder里的multi-head attention。而Encoder的k/v来自masked multi-head attention,masked multi-head attention除了计算k/v外还有因果掩码一个对角矩阵保证模型只能看到左边的句子。
二、训练与推理阶段流程
2.1 训练阶段
- 用户给的是成对文本所以模型同时看到源句与目标句。
- 目标句整体输入,使用因果掩码并行预测每个位置的下一个 token。
- 损失只计算非 pad 部分,反向传播优化。
- 这个时候就利用masked multi-head attention的因果掩码来保证只看到左边,防止模型偷看。Encoder照常生成每个token包含整句意义 K/V的矩阵,如:K = [K_中, K_国, K_的, K_首, K_都, K_是, k_北]
2.2 推理阶段
- 用户只提供源句,模型自回归生成目标句。
- Encoder 生成 memory(每个token包含整句意义 K/V的矩阵),Decoder 逐步生成 token从起始符( <s>)开始
- 每步生成一个新 token,直到遇到结束符(</s> )或达到长度上限。
- 用户在整个预测过程里只提供了“源句”,目标句是模型逐 token 自动生成的。这时的masked multi-head attention只负责生成自己的k/v
三、QKV 矩阵计算与注意力机制
- 所有 token 通过 W_q、W_k、W_v 投影为 Q、K、V 矩阵。
- 计算注意力分数:scores = Q @ K^T / √d (一条矩阵乘就得到 全部 scores) 在scores中 第 i 行已经包含 token-i 与 0…seq-1 所有位置的相似度。
- 加掩码(因果或双向)→ Softmax → 与 V 相乘。attn = softmax(scores) -> Out = attn @ V (同样一次矩阵乘,整句所有位置的加权求和一起完成)
- 输出为加权求和后的表示,经过残差、LayerNorm、FeedForward 等处理 才得到 Encoder 该层的最终表示,再乘 W_k / W_v 才拿到 memory K/V。
四、因果、非因果模型总结
| 模型类型 | 代表模型 | 掩码类型 | 可见范围 | 应用场景 |
|---|---|---|---|---|
| Masked LM | BERT | 双向 | 全文可见 | 理解类任务 |
| Seq2Seq | T5 | Encoder 双向,Decoder 因果 | 源句全文,目标句左向 | 翻译、摘要 |
| Prefix LM | T5、UniLM | 前缀双向,后缀因果 | 前缀全文,后缀左向 | 续写、填空、翻译 |
| Causal LM | GPT、LLaMA | 因果 | 仅左边 | 文本生成、对话 |
- Masked LM(纯 Encoder,BERT 系列)
目标:学会“上下文填词”
做法:
输入:把一句子里 15% 的词换成 [MASK],然后让模型一次性输出这些被遮住的词。
掩码:全向可见(没有三角),位置 i 能看到前后所有词。
训练:并行算整句,一次性预测所有 [MASK]。
推理:还是一次性前向,输出被遮住的词。
用途:文本分类、信息抽取、相似度计算等“理解”任务。 - Seq2Seq(独立 Encoder + Decoder,原版 Transformer)
目标:机器翻译、摘要等“一段变另一段”
做法:
Encoder:把整句原文读一遍,生成一组“上下文向量”。
Decoder:自回归地生成译文,每一步都能回头去“查”Encoder 的向量(交叉注意力)。
掩码:
– Encoder:全向可见
– Decoder:下三角(因果)
训练: teacher-forcing,并行算整句目标语。
推理:自回归,一步一生成。 - Prefix LM(T5、UniLM)——“把 Encoder 和 Decoder 合并到同一套参数里”
目标:续写、填空、翻译都能干
核心思想:
输入拆成两段:
– 前缀(Prefix):双向可见,像 BERT 一样随便看;
– 后缀(Suffix):只能看左边,像 GPT 一样自回归生成。
人为区分前缀、后缀作为训练数据区分用特殊token
前缀(Prefix):输入里被给定的那一段
后缀(Suffix):输入里需要模型生成的那一段
同一堆 Transformer 层,前半段用“全向掩码”,后半段用“因果掩码”。
[Prefix | Suffix]
[p1 p2 p3 | s1 s2 s3]
掩码矩阵
p1 p2 p3 s1 s2 s3
p1 1 1 1 0 0 0 ← p1 只看前缀
p2 1 1 1 0 0 0
p3 1 1 1 0 0 0
s1 1 1 1 1 0 0 ← s1 可看全部前缀+自己
s2 1 1 1 1 1 0
s3 1 1 1 1 1 1
前缀区域 → 全 1(双向,像 BERT)
后缀区域 → 下三角(因果,像 GPT)
训练:一次前向就能同时做“填空”+“续写”。
推理:给定前缀后,自回归生成后缀。
- Causal LM(纯 Decoder,GPT / Llama)
目标:开放式文本生成
做法:
结构:只有 Decoder,没有 Encoder。
掩码:严格的下三角,位置 i 永远看不到 i+1… 未来词。
训练:Next Token Prediction,并行算整句,但用因果掩码模拟“单步生成”。
推理:自回归,一步吐一个 token。
注意:“让模型能看到多少上下文”决定掩码形状,掩码形状决定模型能干什么任务。
五、因果模型总结(Causal LM)
- 只用 Transformer 的 Decoder 部分,并且用因果掩码(Causal Mask)强制“只能看左边”。
- 用因果掩码(下三角矩阵)一次性并行算整句,但让位置 i 只能利用 0…i 的信息 → 模型学会“永远不看未来”。
- 自回归一个一个吐 token,天然只能看已生成的左边;这正是训练时因果掩码所模拟的场景。→ 因果掩码是“能力”,自回归是“用法”;
- 没有掩码,模型在训练时就能偷看未来,推理时即使单步生成也会失效。
六、自回归推理的两个阶段
6.1 Prefill 阶段(填充/初始化)
- 一次性处理用户输入的所有 token。
- 计算初始 logits,生成第一个 token。
- 同时将所有 K/V 写入 KV-cache。
6.2 Decode 阶段(解码/生成)
- 每步只输入一个新 token。
- 取最新 logits → sample → 得到下一个 token。
- 使用 KV-cache 中的历史 K/V 计算注意力。
- 生成新 token 并更新 KV-cache,直到结束。
七、结合 QKV 机制的具体推理流程示例
1. 用户输入(Prefill 阶段)
用户 prompt:
中国的首都是
| 步骤 | 操作 | 说明 |
|---|---|---|
| ① 分词 | 得到 token 序列 | [中, 国, 的, 首, 都, 是](共 6 个 token) |
| ② 一次性前向 | 6 个 token 全部送入模型 | 每层 Transformer 计算 QKV,执行自注意力 |
| ③ 更新表示 | 6 个 token 的 embedding 被刷新 | 每个 token 获得整句加权后的新向量 |
| ④ 提取 KV | 将每层的 K/V 按 (layer, head, seq, dim) 保存 | 写入 KV-cache |
| ⑤ 取最后一位置 | 仅用最末 token 向量 | 过 lm_head → logits → softmax → 采样 |
| ⑥ 得到首个生成 token | 概率最高 = 北 | 序列延长为 7 个:[中, 国, 的, 首, 都, 是, 北] |
2. 继续生成(Decode 阶段)
目标:生成下一个字。
| 子步骤 | 动作 | 细节 |
|---|---|---|
| ① 输入 | 仅送 新生成的单 token "北" | 不再重复计算前面 6 个 |
| ② 计算 QKV | 现算 "北" 的 q, k, v | Q 即时计算,K/V 待追加 |
| ③ 拼接历史 | K_cache = [K_中, ..., K_是, k_北] <br> V_cache 同理 | 与 KV-cache 中前 6 个拼接 |
| ④ 自注意力 | 可见 全部历史位置 | 因 KV-cache 已存之前所有 K/V |
| ⑤ 更新缓存 | 把 "北" 的 k/v 追加写入 | 缓存长度变为 7 |
| ⑥ 采样 | 取 logits → softmax → 选最高概率 | 得到 “京” |
| ⑦ 序列更新 | 现在序列 = [中, 国, 的, 首, 都, 是, 北, 京] | 8 个 token |
3. 循环直到结束
- 重复第 2 步:
- 永远只送 最新 1 个 token 进网络;
- Q 现算,K/V 追加到缓存;
- 注意力每次都能看见 全部历史(靠 KV-cache);
- 终止条件:遇到 <EOS> 或达到长度上限。
八、lm_head 的作用与机制
- 将 Transformer 最后一层隐藏向量映射为词表 logits。
- 通常与 token embedding 共享权重,减少参数量。
- 输出 logits 后通过 softmax 得到概率,采样生成 token。
很多模型(GPT、LLaMA)把 lm_head 权重(向量->分数->贪心->采样-> id) 与 token embedding(token embedding 矩阵就是“id → 向量”的查找表) 矩阵共享(输出层参数 = 输入层参数转置),减少参数量
多头注意力 → 残差+LayerNorm → FFN → 残差+LayerNorm → lm_head
多头注意力体现:
多头注意力内部把 hidden 切成 num_heads × head_dim,做完 Attention 再 concat 回 hidden;lm_head 拿到的已是 concat 后的完整向量,所以看不到“头”维度,只需一次矩阵乘即可
九、推理框架内部处理逻辑(以 vLLM 为例)
用户 prompt → 切成 token → 生成一个 Sequence(一句话)
每个 seq 有唯一 seq_id,状态:{WAITING, RUNNING, SWAPPED}。
伪结构
class Sequence:
seq_id: int
prompt_token_ids: List[int] # 这句话的所有 token id
generated_token_ids: List[int] # 已生成的 token id
status: RUNNING | WAITING | SWAPPED
一共有两个队列 WAITING(等待), RUNNING(运行)。swapped 只是 running 里某些 seq 的“暂存态”即序列的 KV 页被换到 CPU,等 GPU 空位。
一次batch本轮一起 forward 的 token 总数,可以跨多个句子、跨预填充/解码阶段:
batch组成,running 里有 5 条 seq,每条再生成 1 个 token → batch = 5
同时 waiting 里拉来 1 条长 60 token 的 prompt,拆成 chunk=30 → batch += 30取决于(可用预算 = max_num_batched_tokens − 当前 running 已占 token 数)
35 个 token 来自 6 条不同句子,但一次 CUDA kernel 算完,这就叫 一个 batch。
runing的5个token的用于decoder预测下一个token的
waiting是拿新的seq做chunked-prefill(可拆块-预填充)输出 KV-block,如果所有块都处理完进入 runing。
显存不够 → 把 running 队尾 seq 的 KV 页换出到 CPU,等有空位再换回来
token 是最小调度单位 ,GPU 永不空转。
十、PagedAttention 的优势
- 内存块动态分配,无需连续地址,避免碎片。
- 支持乱序映射,块可以不连续。
- 同前缀序列可共享 KV 块,节省显存 60~80%。
十一、两阶段分离(可选)(Splitting Prefill/Decode)
- 痛点:Prefill 算整句,计算量大;Decode 只算 1 token,延迟要求高。
- 老做法:同一实例混跑 → Prefill 一占 SM,Decode 就排队 → 抖动大
SM = Streaming Multiprocessor(流式多处理器)≈ “GPU 核心计算单元”,一张 A100 有 108 个 SM。
vLLM可选方案:
Prefill 实例(大算力 GPU )
– 只负责 chunked-prefill → 输出 KV-block
– 算完通过 NCCL/P2P 异步把块直传到 Decode 实例
Decode 实例(低延迟 GPU—Decode 每步都要“重看”整条历史,带宽随长度线性涨;用户却坐在屏幕前等下一个字,所以延迟要求极高。)
– 永远只跑单 token decode → 每步延迟稳定
– 块已提前到位 → 无等待
十二、对比的来看TGI、LMDeploy
如何拆分预算粒度
| 框架 | 拆分策略 | 粒度 | 混排方式 | 感受 |
|---|---|---|---|---|
| vLLM | token 级拼图 | token | 任意长度实时拆,块地址乱序也能算 | 公交 |
| TGI | request 级接力 | request | 长句才拆 chunk,先吃 chunk 再统一 decode | 地铁 |
| LMDeploy | micro-batch 级砖块 | micro-batch | 切成固定小块,再跟 decode 单字拼进同一次 kernel | 乐高 |
Prefill vs Decode 到底怎么混
1. vLLM:token-level 随时混排(“拼图”)
┌─本轮 CUDA kernel 输入(total_tokens=35)
│ ① decode-0 1tok
│ ② decode-1 1tok
│ ③ decode-2 1tok
│ ④ decode-3 1tok
│ ⑤ decode-4 1tok
│ ⑥ chunk-prefill 30tok(新长句前 30 token)
└──────────────────────────
→ 一次 forward 算完 35 个 token
- 无阶段概念:只要预算有空位,长句拆任意 chunk 与 decode 单字拼在同一张矩阵。
- 矩阵形状
(35, hidden),FlashAttention 统一 kernel 内部分头处理。
2. TGI:request-level 阶段接力(“双队列”)
Phase-1 Prefill(占预算上限 50%)
┌─ CUDA kernel-1(64 tok)──────
│chunk-0 64tok(新长句前 64 token)│
└────────────────────────────────
Phase-2 Decode(剩余预算)
┌─CUDA kernel-2(8 tok)
│decode-0 1tok
│ decode-1 1tok
│ … 8 条
└──────────────────
- 先跑完所有 Prefill chunk,再跑所有 Decode;界限清晰。
- 好处:Prefill 不挤 Decode 的 SM,单字延迟抖动小;代价:多一次 kernel 发射。
3. LMDeploy:micro-batch 砖块内交错(“同 kernel 内混砌”)
- 长句先切成 固定 64-token 砖块(micro-batch),再与 decode 单字拼成同一张矩阵。
- 线程块 ID 分区:
- 线程块 0-3 负责 4 个 micro-batch
- 线程块 4-11 负责 8 个 decode
- 物理上同 kernel,逻辑分区域,无额外 kernel 发射,SM 利用率最高。
显存怎么切块、怎么映射、怎么搬
| 特性 | vLLM | TGI | LMDeploy |
|---|---|---|---|
| 块粒度 | 4 KB ≈ 128 tok | 4 KB ≈ 128 tok | 固定 32/64/128 tok |
| 映射方式 | 虚拟→物理 乱序 | 虚拟→物理 乱序 | 物理连续 slab |
| 换页时机 | 同步(调度线程阻塞) | 同步(保守,尽量不换) | 异步后台线程 |
| 是否阻塞 decode | ✅ 会阻塞 | ✅ 会阻塞 | ❌ 不阻塞(异步) |
| 量化块 | 外部插件 | 外部插件 | 原生 INT4/INT8 块 |
| 地址连续性要求 | ❌ 不要求 | ❌ 不要求 | ✅ 要求连续 slab |
Tensor Core & FlashAttention 速写
- Tensor Core:NVIDIA GPU 专用矩阵乘法硬件单元。
- FlashAttention = 分块 + 重计算,把 Attention 内存访问降一个量级。
- 标准三步:
S=QK^T/√d→P=softmax(S)→O=PV需N×N中间矩阵,三次 HBM (显存)读写,带宽成为瓶颈.。 - FlashAttention 沿 seq 维切
B×B小块,在 SRAM 里在线 softmax,只算不存。
- 标准三步:
FlashAttention
- 将 Attention 计算拆分为小块,避免存储中间矩阵。
- 使用 GPU 片上 SRAM 完成计算,减少 HBM 访问。
- 实现在线 Softmax,保留局部统计信息,避免重复读写。
FlashAttention-2 三级内存瀑布
| 内存级别 | 大小 | 带宽 | 角色 |
|---|---|---|---|
| HBM | 40 GB | 1.6 TB/s | 存 Q/K/V/O |
| SRAM | 192 KB | 19 TB/s | 算 B×B 子矩阵 |
| 寄存器 | 256 B | >100 TB/s | 累加局部 max/sum |
手工调度数据搬运:计算只在 SRAM/HBM 各读一次,带宽瓶颈消失。
十三、显存管理机制对比
| 特性 | vLLM | TGI | LMDeploy |
|---|---|---|---|
| 块粒度 | 4KB ≈ 128tok | 4KB ≈ 128tok | 固定 32/64/128tok |
| 映射方式 | 虚拟→物理乱序 | 虚拟→物理乱序 | 物理连续 slab |
| 换页时机 | 同步阻塞 | 同步(保守) | 异步后台线程 |
| 是否阻塞 decode | ✅ | ✅ | ❌(不阻塞) |
| 量化块支持 | 插件支持 | 插件支持 | 原生 INT4/INT8 |
| 地址连续性要求 | ❌ | ❌ | ✅(连续 slab) |
十四、压测环境与准备
| 组件 | 版本/配置说明 |
|---|---|
| GPU | CH20 140GB ×1 |
| 模型 | Llama-2-7B-chat |
| 框架版本 | vLLM 0.5.1/ LMDeploy 0.4.0 |
| 压测脚本 | profile_throughput.py |
| 测试接口 | OpenAI-compatible API |
| 测试参数 | prompt=512 tokens, output=128 tokens, concurrency=10/50/100 |
十五、框架启动命令
vLLM
python -m vllm.entrypoints.openai.api_server \
--model ./Llama-2-7b-chat-ms \
--dtype float16 \
--port 8801 \
--max-model-len 2048 \
--max-num-batched-tokens 16384 \
--max-num-seqs 256
默认配置
python -m vllm.entrypoints.openai.api_server --model ./Llama-2-7b-chat-ms --dtype float16 --port 8801 --max-model-len 2048 --served-model-name Llama-2-7b-chat-ms
连续批处理(continuous batching)配置
python -m vllm.entrypoints.openai.api_server --model ./Llama-2-7b-chat-ms --dtype float16 --port 8801 --max-model-len 2048 --served-model-name Llama-2-7b-chat-ms --max-num-batched-tokens 16384 --max-num-seqs 256
| 参数 | 作用 | 你设的值 |
|---|---|---|
| –max-num-batched-tokens | 一个 forward 里最多同时处理多少 token(prefill+decode 一起算) | 16384 |
| –max-num-seqs | 同一个时刻最多允许多少条序列挤在 batch 里 | 256 |
查看id curl http://localhost:8801/v1/models
请求测试
curl http://localhost:8801/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Llama-2-7b-chat-ms",
"messages": [{"role": "user", "content": "Hello"}],
"max_tokens": 20
}'
LMDeploy
lmdeploy serve api_server ./Llama-2-7b-chat-ms \
--server-port 8803 \
--tp 1 \
--cache-max-entry-count 0.8
并发
lmdeploy serve api_server ./Llama-2-7b-chat-ms \ --server-name 0.0.0.0 \ --server-port 8801 \ --model-name Llama-2-7b-chat-ms \ --cache-max-entry-count 0.6 \ --max-batch-size 256 \ --tp 4
| 参数 | 说明 |
|---|---|
--server-port 23333 | RESTful API 监听端口 |
--cache-max-entry-count 0.4 | KV-cache 占用显存比例,范围 0~1 |
--session-len 4096 | 最大上下文长度 |
--tp 2 | 张量并行卡数(多 GPU) |
--quant-policy 1 | 开启 KV-cache 量化 |
十六、压测命令
脚本:https://github.com/Wuzheyuan456/llama2-7b-alpaca-zh/tree/main/stress-testing
python profile_throughput.py \
--backend openai-chat \
--host localhost --port 8801 \
--tokenizer ./Llama-2-7b-chat-ms \
--num-prompts 1000 \
--prompt-tokens 512 \
--output-tokens 128 \
--concurrency 50 \
--csv llama7b_vllm_c50.csv
十七、压测结果汇总(Llama-2-7B, A100 80G, FP16)
| 框架 | 并发 | 成功请求 | 总耗时 (s) | 总生成 tokens | Throughput (tok/s) | TTFT 平均 (ms) | TTFT 95th (ms) | Request 平均延迟 (ms) | 特殊配置 |
|---|---|---|---|---|---|---|---|---|---|
| vLLM | 10 | 1000/1000 | 62.83 | 77174 | 1228.21 | 623.11 | 1049.14 | 623.11 | 默认 |
| vLLM | 50 | 1000/1000 | 21.34 | 77834 | 3647.51 | 1033.28 | 1743.26 | 1033.28 | 默认 |
| vLLM | 100 | 1000/1000 | 18.16 | 76435 | 4209.96 | 1723.67 | 2986.94 | 1723.67 | 默认 |
| vLLM | 10 | 1000/1000 | 191.64 | 76110 | 397.16 | 1900.78 | 4113.53 | 1900.78 | –max-num-batched-tokens 16384 --max-num-seqs 256 |
| vLLM | 50 | 1000/1000 | 59.93 | 79583 | 1327.88 | 2867.70 | 6055.14 | 2867.70 | –max-num-batched-tokens 16384 --max-num-seqs 256 |
| vLLM | 100 | 1000/1000 | 36.12 | 75701 | 2096.02 | 3386.09 | 6545.83 | 3386.09 | –max-num-batched-tokens 16384 --max-num-seqs 256 |
| vLLM | 10 | 1000/1000 | 198.88 | 75698 | 380.62 | 1972.33 | 4313.34 | 1972.33 | –max-num-batched-tokens 8192 --max-num-seqs 128 |
| vLLM | 50 | 1000/1000 | 55.36 | 78719 | 1422.04 | 2664.29 | 4975.63 | 2664.29 | –max-num-batched-tokens 8192 --max-num-seqs 128 |
| vLLM | 100 | 1000/1000 | 28.30 | 77851 | 2750.77 | 2524.29 | 5684.57 | 2524.29 | –max-num-batched-tokens 8192 --max-num-seqs 128 |
| vLLM | 10 | 1000/1000 | 230.68 | 76701 | 332.50 | 2276.71 | 5077.38 | 2276.71 | –max-num-batched-tokens 4096 --max-num-seqs 64 |
| vLLM | 50 | 1000/1000 | 63.89 | 77254 | 1209.20 | 3076.16 | 6216.20 | 3076.16 | –max-num-batched-tokens 4096 --max-num-seqs 64 |
| vLLM | 100 | 1000/1000 | 46.53 | 76994 | 1654.78 | 4247.45 | 6824.87 | 4247.45 | –max-num-batched-tokens 4096 --max-num-seqs 64 |
| LMDeploy | 10 | 1000/1000 | 339.76 | 116774 | 343.70 | 3388.69 | 3990.70 | 3388.69 | 默认 |
| LMDeploy | 50 | 1000/1000 | 193.73 | 116482 | 601.25 | 9614.02 | 11513.87 | 9614.02 | 默认 |
| LMDeploy | 100 | 1000/1000 | 178.32 | 116409 | 652.81 | 17645.12 | 23737.31 | 17645.12 | 默认 |
| LMDeploy | 10 | 1000/1000 | 235.25 | 115396 | 490.53 | 2341.88 | 3469.03 | 2341.88 | 未注明(非默认优化) |
| LMDeploy | 50 | 1000/1000 | 123.80 | 116125 | 938.03 | 6096.04 | 7719.60 | 6096.04 | 未注明(非默认优化) |
| LMDeploy | 100 | 1000/1000 | 104.74 | 116360 | 1110.90 | 10216.09 | 13031.25 | 10216.09 | 未注明(非默认优化) |
vLLM 主打低延迟,LMDeploy 主打高吞吐;并发越高,两者差距越极端。
十八、结论与选型建议
| 场景需求 | 推荐框架 | 理由说明 |
|---|---|---|
| 高吞吐、离线批量推理 | LMDeploy | CUDA 优化极致,吞吐最高 |
| 低延迟、交互式对话 | vLLM | TTFT 最小,适合实时响应 |
| 企业部署、功能丰富 | TGI | 支持量化、投机解码、日志完善 |
📎 附录:
- 所有测试基于公开脚本与模型,结果可复现。
5943

被折叠的 条评论
为什么被折叠?



