这是「大模型部署学习路线」的第一课(L1 推理基础)。 学完这一篇,你将能手算一个模型占多少显存、看懂 TTFT / TPOT / 吞吐这些指标,从此调参不再靠感觉,而是靠算。

一、 推理的本质:模型在"算"什么

先说清楚一个最底层的事实:大模型不会一次性"想好"整段回答,它是逐个词(token)往外"吐"的。

你发一句"帮我写一首诗",模型内部的真实过程是:

  1. 把你这句话切成一串 token(约 10~20 个);

  2. 读完全部输入后,算出第一个输出 token 的概率分布,挑一个;

  3. 把这个 token 拼到输入末尾,再算下一个 token;

  4. 重复第 3 步,直到吐出一个"结束"符号。

所以"一次推理"= 一次 Prefill(处理全部输入)+ 很多次 Decode(每吐一个词算一次)。

理解不了这一点,后面所有的优化技术都看不懂。因为它直接决定了:

  • 为什么"首 token 慢、后面快";

  • 为什么显存里除了权重还要存别的;

  • 为什么并发一高,显存就爆。


二、推理两阶段:Prefill vs Decode

Prefill(预填充):处理全部输入,算出第一个词

  • 做什么:把你的 prompt 全部喂进模型,一次性并行计算所有输入 token 的中间状态。

  • 特点:计算密集、可以并行,一瞬间要算一大堆矩阵乘法。

  • 结果:得到第一个输出 token,同时把每个输入 token 的 K、V 向量缓存起来(这就是后面的 KV Cache)。

  • 为什么慢:它要处理的是整个上下文(比如几千个 token),计算量 = 输入长度 × 模型大小。

Decode(解码):逐 token 自回归生成

  • 做什么:每步只基于"上一个 token + 缓存",算出下一个 token。

  • 特点:串行、只能一个一个来,每步计算量小,但无法并行

  • 为什么慢:生成 1000 个词就要串行跑 1000 步,每一步的延迟(TPOT)决定总耗时。

  • 瓶颈:Decode 阶段往往不是"算力不够",而是"显存带宽不够"——每步都要把整层权重从显存搬一遍,但只算一个 token。

一张表看懂两阶段的差异

维度

Prefill

Decode

处理对象

全部输入 token(N 个)

1 个新 token

并行度

高(N 个 token 同时算)

低(只能串行)

计算量

大(随输入长度线性增长)

小(每步固定)

瓶颈

算力(compute-bound)

显存带宽(memory-bound)

对应指标

TTFT(Time To First Token)

TPOT(Time Per Output Token)

直觉

读完整张卷子

逐字念答案

一句话:Prefill 决定你"多久听到第一个字",Decode 决定你"多久听完一整段"。


三、显存账本:显存 ≈ 权重 + KV Cache + 激活值

把显存想象成一张记账卡,跑一个模型时,占显存的主要是三项:

显存 ≈ 模型权重 + KV Cache + 激活值

第一项:模型权重(固定开销)

权重就是模型的参数本身。计算公式:

权重显存 = 参数量 × 每参数字节数

不同精度下每个参数的字节数:

精度

每参数字节

7B 模型

70B 模型

FP32

4 字节

28 GB

280 GB

FP16 / BF16

2 字节

14 GB

140 GB

INT8 / FP8

1 字节

7 GB

70 GB

INT4 / FP4

0.5 字节

3.5 GB

35 GB

看两个结论:

  1. 一个 70B 的模型,FP16 下光权重就要 140GB——单张 80GB 的 A100/H100 根本放不下,这就是为什么大模型要"分卡"(张量并行)或者"量化"(降精度)。

  2. 7B FP16 = 14GB,一张 24GB 的消费级显卡(如 RTX 4090)勉强能装,这也是 7B 系列"人人都能跑"的原因。

第二项:KV Cache(随对话变长、随并发暴涨)

这是最容易被忽略、也是上线后最先爆显存的一项。

模型在 Decode 阶段,每读一个 token,都要拿它去和之前所有 token 算"注意力"。为了不把之前的 token 重新算一遍,模型把每个 token 的 K、V 向量缓存了下来——这就是 KV Cache。

单个请求的 KV Cache 大小:

KV Cache(每请求)≈ 2 × 层数 × hidden_size × 序列长度 × 每参数字节数

以 7B 模型(假设 32 层、hidden=4096、FP16)为例,每个 token 大约要占:

2 × 32 × 4096 × 2 字节 ≈ 512 KB / token

换算成不同上下文长度的单请求 KV Cache:

上下文长度

单请求 KV Cache

2K(2048)

约 1 GB

8K(8192)

约 4 GB

32K(32768)

约 16 GB

128K(131072)

约 64 GB

如果同时有 N 个请求在跑(并发),KV Cache 还要再乘 N

并发数

8K 上下文 × 并发

32K 上下文 × 并发

4

16 GB

64 GB

8

32 GB

128 GB

16

64 GB

256 GB

这就是为什么"长上下文 + 高并发"是显存杀手:128K 上下文、16 并发时,KV Cache 轻松上千 GB,比权重本身还大得多。

第三项:激活值(瞬时中间量)

前向计算过程中,每一层的中间结果(激活值)也要占显存。它的特点是:

  • :可能和权重一个量级,甚至更大;

  • 瞬时:算完当前层,前面的就可以释放;

  • 由框架管理:算子融合、激活重计算(activation checkpointing)就是为了压缩它。

对使用者来说,激活值一般不用精确手算——知道它存在、理解它为什么波动即可。真正要手算的是权重 + KV Cache

进阶:如果模型是 MoE 架构(如 DeepSeek)呢?

前面算的都是稠密模型(每个 token 用全部参数)。现在很多大模型——比如 DeepSeek-V3——改用 MoE(混合专家,Mixture of Experts)架构:把一个大 FFN 拆成一堆小"专家",每个 token 只唤醒其中少数几个(top-2)。这让显存账本出现两个不同的"参数量"

总参数:决定权重显存(部署时所有专家必须全部装进显存) 激活参数:决定算力(每个 token 实际只计算这一小部分)

对比项

稠密模型(例)

MoE(DeepSeek-V3)

总参数

67B

671B

每 token 激活参数

67B

37B

权重显存(FP8 约)

67 GB

671 GB

每 token 算力需求

低(≈37B 水平)

对三项账本分别意味着:

  • 权重(开销变大):所有专家参数必须常驻显存。DeepSeek-V3 共 671B 参数,FP8 也要约 671GB,单卡根本放不下——这就是为什么 MoE 模型天生要多卡部署,并引出专家并行(EP)

  • KV Cache(完全不变):KV Cache 只跟注意力层(层数、hidden_size)有关,MoE 换掉的只是 FFN。所以前面那套 KV Cache 公式对 MoE 模型照用不误。

  • 激活值(反而更小):每层只算 2 个专家,中间结果比全量 FFN 小得多。

一句话:MoE 是"用显存换算力"——权重开销大、KV Cache 照旧,但每 token 算得快、吞吐高。这也是为什么 DeepSeek 这类 MoE 模型部署时"贵的在显存,省的在算力"。

一页纸总结显存账本

显存账本 = 权重(固定,随模型/精度变) + KV Cache(随上下文长度 × 并发数变,最需要监控) + 激活值(瞬时,框架自动管理) 

例子(稠密 7B FP16):权重 14GB;8K 上下文、8 并发时 KV Cache 约 32GB → 需要显存 ≈ 14 + 32 + 激活 ≈ 50GB 左右,单卡 4090 装不下 

MoE 模型(如 DeepSeek-V3):权重按总参数 671B 算(≈671GB FP8) KV Cache 公式不变,但每 token 只算 37B,算力省、吞吐高

四、四个核心指标:TTFT / TPOT / 吞吐 / 显存占用

看懂压测报告、评估部署方案,就看这四个数。它们正好对应前面讲的原理。

1. TTFT(Time To First Token):首 token 延迟

  • 定义:从发出请求到收到第一个输出 token 的时间。

  • 对应:Prefill 阶段(处理全部输入)。

  • 直觉:打开对话页面后,要等多久才开始"打字"。

  • 影响因素:输入长度、模型大小、并发争抢。

  • 合理范围:一般希望 < 1~2 秒(长文档分析场景可以放宽)。

2. TPOT(Time Per Output Token):每输出一个 token 的耗时

  • 定义:生成阶段,每吐一个 token 平均耗时(毫秒级)。

  • 对应:Decode 阶段(逐字生成)。

  • 直觉:开始"打字"后,每隔多久蹦出一个字。

  • 影响因素:显存带宽、模型大小、是否量化。

  • 换算:TPOT = 100ms 时,每秒生成 10 个 token;2000 字的回答(约 2000 token)要 200 秒。

3. 吞吐(Throughput):系统每秒能产出多少 token

  • 定义:整个服务单位时间产出的 token 总数(tokens/s)。

  • 直觉:这是"产能",不是"速度"——系统总的产出能力。

  • 关键:吞吐和单用户延迟往往打架:并发越高、吞吐越高,但每个用户变慢。调优就是在两者间找平衡。

4. 显存占用(显存利用率)

  • 定义:权重 + KV Cache + 激活值占了多少显存。

  • 作用:决定你最多能开多少并发

  • 直觉:显存是硬约束——权重装不下就跑不起来,KV Cache 装不下就只能砍并发或砍上下文。

四指标速查表

指标

回答什么问题

对应阶段

越差说明

TTFT

多久听到第一个字?

Prefill

输入太长 / 算力不足

TPOT

每蹦一个字要多久?

Decode

带宽瓶颈 / 模型太大

吞吐

系统总共能产多少?

整体

并发设计 / 批处理策略差

显存

能同时服务多少人?

整体

上下文太长 / 并发太高

怎么用这四个指标调参(不再靠感觉)

显存不够 → 砍 KV Cache(限上下文 / 限并发)或量化(INT8/INT4) 
首 token 慢 → 看 TTFT:输入过长?并发过高? 
生成太慢 → 看 TPOT:换更高带宽显卡?量化?投机解码? 
整体产能低 → 看吞吐:提高并发 / 开启 Continuous Batching

五、学完这一层,你能做什么

  1. 手算显存:拿到一个模型,5 分钟算出"权重多少、KV Cache 涨多快、单卡装不装得下";

  2. 预判并发上限:显存剩多少,除以单请求 KV Cache,就知道能开几个并发;

  3. 看懂压测报告:别人给的 TTFT / TPOT / 吞吐数字,你一眼能看出系统瓶颈在 Prefill 还是 Decode;

  4. 调参有依据:vLLM 里的 max-model-len--gpu-memory-utilization、量化选项,每个参数背后都是这份账本。


一句话总结

推理 = 一次 Prefill + 无数次 Decode;显存 = 权重(固定)+ KV Cache(随上下文和并发暴涨)+ 激活值(瞬时);TTFT 管"第一句话",TPOT 管"说话速度",吞吐管"总产能",显存管"能装多少人"。把这张账本刻进脑子里,大模型部署的大门就为你打开了。

更多推荐