大模型基础扫盲------从文本到 Token、Embedding、QKV 与 Transformer(不定期优化修改)大模型处理文本的全流程解析(四)
大模型基础扫盲------从文本到 Token、Embedding、QKV 与 Transformer 大模型处理文本的全流程解析(一)-CSDN博客
大模型基础扫盲------从文本到 Token、Embedding、QKV 与 Transformer(不定期优化修改)大模型处理文本的全流程解析(二)-CSDN博客
大模型基础扫盲------从文本到 Token、Embedding、QKV 与 Transformer(不定期优化修改)大模型处理文本的全流程解析(三)-CSDN博客
17. 推理优化:KV Cache、Prefill、Decode
17.1 推理的两个阶段
自回归推理通常分为两个阶段。
|
阶段 |
做什么 |
特点 |
关键指标 |
|---|---|---|---|
|
Prefill |
用户 prompt 第一次进入模型,一次性处理所有输入 token |
计算密集,可并行,生成整段 KV Cache |
TTFT,Time To First Token |
|
Decode |
逐 token 生成,每步只处理 1 个新 token |
串行依赖,显存带宽压力大,KV Cache 越来越长 |
TPOT,Time Per Output Token,或 tokens/s |
MLOps 视角:
优化 Prefill 主要靠:
GPU 算力,FLOPS
优化 Decode 主要靠:
显存带宽,memory bandwidth
这也是为什么 Decode 阶段经常是推理服务瓶颈。
17.2 KV Cache 的原理
没有 KV Cache 时:
生成第 1000 个 token 时,
需要重新计算 token 1~999 的 K、V。
有 KV Cache 时:
把前面 token 的 K、V 缓存起来。
生成第 1000 个 token 时,
只计算 token 1000 的 Q、K、V,
然后让新的 Q 去和缓存中的 K、V 做注意力。
收益:
大幅减少重复计算,提高生成速度。
代价:
占用额外显存。
17.3 KV Cache 显存估算
通用公式:
KV Cache 显存
= 2
× num_layers
× num_kv_heads
× head_dim
× seq_len
× bytes_per_param
× batch_size
其中:
2 代表 K 和 V 两份。
num_kv_heads 是 KV 头数,不是 Q 头数。
bytes_per_param 通常是 2,对应 FP16/BF16。
示例:Mistral-7B 风格配置
假设:
num_layers = 32
num_kv_heads = 8
head_dim = 128
seq_len = 4096
dtype = BF16,每参数 2 bytes
单条序列:
2 × 32 × 8 × 128 × 4096 × 2
= 536,870,912 bytes
≈ 0.5 GB
如果:
batch_size = 32
则:
0.5 × 32 = 16 GB
如果某个模型是 4 个 KV heads,那么同样条件下大约是:
0.25 GB / 单条序列
注意:
不同模型的 KV 头数差异很大。
做容量规划时,务必以目标模型 config.json 中的:
num_key_value_heads
为准,不要凭记忆估算。
17.4 vLLM 的 PagedAttention
传统方式:
为每个请求预分配最大长度的连续 KV Cache 显存。
问题:
大量显存被浪费。
PagedAttention:
把 KV Cache 切成固定大小的“页”,按需分配。
类似操作系统的虚拟内存分页。
你做过容器,对“分页”概念不会陌生。
PagedAttention 就是把 OS 虚拟内存思想用到 GPU 显存管理上。
17.5 连续批处理,Continuous Batching
传统批处理:
等一批请求全到齐。
一起推理。
一起返回。
问题:
短请求要等长请求,浪费吞吐。
连续批处理:
某个请求生成完毕就立刻移出。
新请求立刻插入。
好处:
GPU 利用率更高。
在线服务吞吐更好。
17.6 KV Cache 的更精确估算方式
KV Cache 的通用估算公式是:
KV Cache 显存
= 2
× num_layers
× num_kv_heads
× head_dim
× cached_tokens
× bytes_per_element
其中:
2 表示 K 和 V 两份。
num_layers 是 Transformer 层数。
num_kv_heads 是 KV 头数,不是 Q 头数。
head_dim 是每个注意力头的维度。
cached_tokens 是当前已经缓存的 token 数量。
bytes_per_element 是每个元素占用的字节数。
常见精度:
FP16 / BF16:2 bytes
FP8:1 byte
INT8:1 byte,具体取决于实现
如果是 batch 推理:
cached_tokens 不应该简单理解成:
batch_size × max_seq_len
更准确地说,应该是所有请求当前已缓存 token 数的总和:
cached_tokens = sum(
prompt_len_i + generated_len_i
)
也就是:
KV Cache 显存
= 2
× num_layers
× num_kv_heads
× head_dim
× sum(prompt_len_i + generated_len_i)
× bytes_per_element
举例:
假设:
num_layers = 32
num_kv_heads = 8
head_dim = 128
dtype = BF16,每个元素 2 bytes
一条请求缓存 4096 个 token:
2 × 32 × 8 × 128 × 4096 × 2
= 536,870,912 bytes
≈ 0.5 GB
如果有 32 条请求,每条都缓存 4096 个 token:
0.5 GB × 32 = 16 GB
但如果这些请求共享相同 system prompt,并且推理框架支持 prefix caching,那么公共前缀的 KV Cache 可以共享。
例如 32 条请求都有 2048 个 token 的相同 system prompt。
这部分理论上可以只存一份,或者通过页表共享。
MLOps 视角:
KV Cache 是推理显存的大头之一。
尤其是在长上下文和高并发场景下,KV Cache 往往比模型权重更容易成为瓶颈。所以部署时要重点关注:
num_key_value_heads max_model_len batch size prompt 长度 输出长度 是否开启 prefix caching 是否使用 FP8 KV Cache 是否使用 PagedAttention
17.7 PagedAttention 和操作系统分页的关系
你做过容器和运维,对虚拟内存、分页、按需分配这些概念不会陌生。
传统 KV Cache 分配方式类似:
给每个请求预分配一段连续显存。
即使这个请求最后只用了一半长度,
剩下的显存也可能被浪费。
这很像早期连续内存分配的问题:
内存碎片严重
利用率低
无法灵活扩容
PagedAttention 的做法类似操作系统虚拟内存分页:
把 KV Cache 切成固定大小的 block。
每个 block 可以存固定数量 token 的 K、V。
请求需要多少 block,就分配多少 block。
不要求物理显存连续。
通过页表或 block table 管理逻辑块和物理块的映射。
好处:
减少显存碎片。
提高 batch size。
提升 GPU 吞吐。
更容易实现 prefix caching。
在 vLLM 中,你会经常看到类似概念:
block_size
block table
physical block
logical block
copy-on-write
prefix caching
这些本质上都是显存管理优化。
MLOps 视角:
如果你要部署高并发 LLM 服务,PagedAttention 几乎是必学内容。
因为它直接影响:吞吐 显存利用率 首 token 延迟 长文本支持能力
18. 显存估算:从原理到工程
18.1 推理显存估算公式
推理时的显存消耗通常包括四部分:
1. 模型权重
2. KV Cache
3. 激活值
4. 临时缓冲和碎片
粗略公式:
推理显存
≈ 模型权重
+ KV Cache
+ 激活值
+ 临时缓冲
模型权重估算:
weights_memory
≈ param_count × bytes_per_param
例如:
7B 模型,BF16:
7,000,000,000 × 2 bytes ≈ 14 GB
KV Cache 估算:
kv_memory
= 2
× num_layers
× num_kv_heads
× head_dim
× cached_tokens
× bytes_per_element
激活值:
激活值和以下因素强相关:
batch_size
seq_len
hidden_size
推理框架的算子实现
是否使用 CUDA Graph
是否使用算子融合
临时缓冲:
通常建议预留 10%~20% 的额外空间。
所以在生产环境中,不能只算模型权重。
例如一张 24GB 显卡:
能装下 14GB 的 7B BF16 权重,
不代表能稳定跑 7B 长上下文服务。
因为 KV Cache 和激活值还会继续吃显存。
18.2 训练显存估算
训练显存比推理复杂得多。
全参数训练时,通常要考虑:
1. 模型权重
2. 梯度
3. 优化器状态
4. 激活值
5. 通信缓冲区
6. 临时 buffer
以常见的 BF16 训练 + AdamW 为例:
模型权重:BF16,约 2 bytes/param
梯度:BF16,约 2 bytes/param
AdamW 优化器状态:
FP32 master weights:4 bytes/param
FP32 first moment:4 bytes/param
FP32 second moment:4 bytes/param
合计:
2 + 2 + 4 + 4 + 4 = 16 bytes/param
所以:
全参数训练显存粗略估算
≈ param_count × 16 bytes
+ 激活值
+ 通信缓冲区
+ 临时 buffer
例如:
7B 模型:
7,000,000,000 × 16 bytes ≈ 112 GB
这还没有算激活值。
所以朴素单卡全参数训练 7B,经常会超过 100GB 显存。
这就是为什么实际工程中经常使用:
ZeRO
FSDP
DeepSpeed
activation checkpointing
8-bit Adam
LoRA
QLoRA
参数高效微调
MLOps 视角:
如果你要做微调平台,不能只问用户“模型多大”。
还要问:是否全参数训练 是否使用 LoRA 序列长度多少 batch size 多少 是否开启 gradient checkpointing 优化器是什么 精度是什么 是否多机多卡 通信后端是 NCCL 还是其他这些都会直接影响显存和集群资源规划。
另外,
16 bytes/param是常见混合精度 AdamW 的粗略估算,具体框架和实现可能略有差异。
19. Padding Mask 与特殊 Token
19.1 Padding Mask
训练时多个句子组成 batch,长度可能不一样。
为了组成矩阵,需要补齐。
例如:
seq1: 我 吃 鱼
seq2: 你 看 [PAD]
对应 attention mask 可能写成:
[
[1, 1, 1],
[1, 1, 0]
]
其中:
1 表示可以关注
0 表示屏蔽
[PAD] 位置不应被关注,所以需要 padding mask 屏蔽。
19.2 特殊 Token
常见特殊 token:
|
token |
作用 |
|---|---|
|
|
填充短序列 |
|
|
句子开始 |
|
|
句子结束,生成时遇到即停止 |
|
|
常用于分类任务,BERT 常见 |
|
|
分隔两个句子,BERT 常见 |
|
|
未知 token,现代字节级 tokenizer 中可能很少触发 |
|
chat 特殊 token |
用于系统、用户、助手消息模板 |
注意:
采用字节级分词的模型通常能表示任意 UTF-8 文本,
所以通常不会因为罕见字符直接失败。
但具体是否保留 <unk>,以及有哪些 special token,
要以模型 tokenizer 配置为准。
19.3 chat template 必须正确
现在大量开源模型都是 chat 模型。
chat 模型通常有自己的对话模板。
例如:
system
user
assistant
不同模型的模板可能完全不同。
正确做法是:
tokenizer.apply_chat_template()
而不是自己手拼字符串。
例如伪代码:
messages = [
{"role": "system", "content": "你是一个运维专家。"},
{"role": "user", "content": "请解释 KV Cache。"}
]
prompt = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
MLOps 视角:
chat template 错误是非常常见的生产事故。可能导致:
模型角色混乱 输出格式错误 无法正常停止 重复输出 user prompt 工具调用失败 多轮对话上下文错乱部署前一定要检查:
tokenizer_config.json重点关注:
chat_template eos_token bos_token pad_token additional_special_tokens如果模型支持 tool calling,还要检查 tool 相关 token 和格式说明。
20. 常见误解
|
# |
误解 |
纠正 |
|---|---|---|
|
1 |
token id 有语义 |
id 只是编号,语义在 embedding 里 |
|
2 |
token 一定是一个词 |
可以是字、子词、标点、字节、特殊符号 |
|
3 |
embedding 是简单格式转换 |
是训练出来的语义表示 |
|
4 |
模型天然知道 token 顺序 |
注意力本身对顺序不敏感,需要位置编码 |
|
5 |
自回归模型可以看到整个句子 |
GPT 类模型只能看到当前位置及之前 |
|
6 |
Transformer 只有注意力 |
每层还包括 FFN、残差、归一化 |
|
7 |
模型真的懂主谓宾 |
模型从海量文本学到语言模式,不是显式语法分析 |
|
8 |
Q、K、V 是唯一可能的结构 |
是 Transformer 的设计选择,也有 Mamba、线性注意力等替代方案 |
|
9 |
所有模型都用 LayerNorm |
许多现代大模型用 RMSNorm,但非绝对 |
|
10 |
FFN 只有两个矩阵 |
SwiGLU 风格 FFN 常见有三个矩阵 |
|
11 |
FFN 只占模型参数的 1/3 |
单个 block 中 FFN 常占约 2/3,整模型占比视词表、embedding、MoE 而定 |
| 12 |
Embedding 向量就是词义的最终表示 |
输入层 embedding 只是初始表示。 真正携带上下文语义的是 Transformer 各层输出的 hidden state。 |
| 13 |
一个多义词在 embedding table 中一定有多个向量 |
通常不是。 一个 token 通常只有一个初始 embedding。 多义区分主要靠后续 Attention 和上下文表示。 |
| 14 |
词表越大越好 |
词表大可以让中文、代码等文本更短,减少 token 数, 但也会增加 embedding 和 LM Head 参数量。 需要综合权衡。 |
| 15 |
max_position_embeddings 就是模型一定稳定支持的长度 |
不一定。 还要看训练数据长度分布、RoPE scaling、推理框架配置和长文本实际评测结果。 |
| 16 |
KV Cache 只和 batch_size 有关 |
KV Cache 和层数、KV 头数、head_dim、缓存 token 总数、精度都有关。 长上下文场景下尤其明显。 |
| 17 |
推理显存主要就是模型权重 |
长上下文和高并发场景下, KV Cache、激活值、临时缓冲、显存碎片都可能成为主要瓶颈。 |
21. 全文总结
21.1 核心概念速查表
|
概念 |
通俗解释 |
|---|---|
|
文本 |
人类可读的字符串 |
|
分词器 |
把文本切成 token 的工具 |
|
token |
模型处理文本的基本单位 |
|
token id |
token 在词表中的编号,本身无语义 |
|
embedding |
把 token id 变成语义向量 |
|
位置编码 |
告诉模型 token 的顺序 |
|
Q |
查询向量:我在找什么 |
|
K |
键向量:我能被什么找到 |
|
V |
值向量:找到我后我提供什么 |
|
|
计算 token 之间的相关性分数 |
|
softmax |
把分数变成权重 |
|
因果掩码 |
防止自回归模型偷看后文 |
|
多头注意力 |
从多个子空间做注意力 |
|
GQA |
共享 KV 头,减少 KV Cache |
|
|
把多头结果投影回模型主维度 |
|
LayerNorm / RMSNorm |
归一化,让训练更稳定 |
|
FFN |
对每个 token 做非线性加工 |
|
SwiGLU |
常见现代 FFN 结构,通常有三个矩阵 |
|
残差连接 |
帮助深层网络训练 |
|
多层 Transformer |
逐层提取更丰富的表示 |
|
Weight Tying |
输入 embedding 和输出 LM Head 可能共享权重 |
|
交叉熵损失 |
训练模型预测正确 token |
|
LM Head |
把最后一层向量映射到词表概率 |
|
Prefill |
推理时并行处理 prompt |
|
Decode |
推理时逐步生成 token |
|
KV Cache |
推理时缓存 K、V,提高生成速度 |
21.2 最简流程图
原始文本
↓
Tokenizer
↓
tokens
↓
token ids
↓
Embedding
↓
位置信息注入
├── 绝对位置编码:加到 embedding
└── RoPE:在 Attention 内旋转 Q/K
↓
Transformer Block × N
├── RMSNorm
├── Attention
│ ├── Q/K/V 投影
│ ├── QK^T / sqrt(d_k)
│ ├── causal mask
│ ├── softmax
│ └── 加权 V
├── 残差连接
├── RMSNorm
├── FFN / SwiGLU
└── 残差连接
↓
最后一个位置的 hidden state
↓
LM Head
↓
logits
↓
softmax
↓
下一个 token 概率分布
↓
采样 / greedy / top-k / top-p
↓
生成下一个 token
21.3 一句话总结增强版
如果用一句话概括现代 LLM:
Tokenizer 把文本变成 token,
Embedding 给 token 一个初始语义坐标,
位置编码告诉模型 token 的顺序,
Transformer 通过 Attention 和 FFN 逐层构造上下文语义,
LM Head 最终输出下一个 token 的概率分布。
也就是说:
模型不是简单查表。
模型是在海量文本上训练出来的、
能够根据上下文预测下一个 token 的概率函数。
22. 完整例子:从“我吃鱼”到模型输出
假设输入:
我吃鱼
第一步:分词器切分
可能切成:
我 / 吃 / 鱼
第二步:查 token id
|
token |
token id |
|---|---|
|
我 |
2513 |
|
吃 |
1892 |
|
鱼 |
3765 |
得到:
[2513, 1892, 3765]
注意:这些 id 只是示例。
第三步:查 embedding
|
token |
embedding |
|---|---|
|
我 |
向量 A |
|
吃 |
向量 B |
|
鱼 |
向量 C |
得到:
X = [A, B, C]
第四步:位置信息
如果是绝对位置编码:
我:A + position_1
吃:B + position_2
鱼:C + position_3
如果是 RoPE:
此时不直接加位置向量。
后面 Attention 中会对 Q/K 做旋转。
第五步:生成 Q、K、V
每个 token 向量都会经过三副“滤镜”:
Q = X W_Q
K = X W_K
V = X W_V
得到:
|
token |
Q |
K |
V |
|---|---|---|---|
|
我 |
|
|
|
|
吃 |
|
|
|
|
鱼 |
|
|
|
第六步:计算注意力分数
如果是自回归模型,需要加因果掩码。
处理“吃”时,它只能看到:
我、吃
不能看到后面的:
鱼
所以“吃”的 Query:
q^(2)
只能和:
k^(1), k^(2)
计算注意力,不能和:
k^(3)
计算。
这一点很重要:
在自回归模型中,
“吃”在这个位置还不知道后面是“鱼”。
它只知道前面是“我”。
第七步:softmax 变权重
假设在自回归模型中,处理“吃”时得到:
|
目标 token |
权重 |
|---|---|
|
我 |
0.60 |
|
吃 |
0.40 |
|
鱼 |
0.00,因为被 mask |
第八步:加权 V
“吃”的新向量:
output^(2)
= 0.60 · v^(1)
+ 0.40 · v^(2)
+ 0.00 · v^(3)
这样,“吃”融合了前文信息:
谁在吃:我
但此时它还不知道吃的是什么,因为在自回归模型中它不能看到后面的“鱼”。
第九步:多头输出经过 W_O
如果有多个头,每个头都会得到一个输出。
这些输出会被拼接,然后经过输出投影矩阵 W_O 映射回模型主维度。
例如:
[head_1, head_2, ..., head_32]
→ concat
→ W_O
→ 4096 维
第十步:残差连接和归一化
注意力输出通常会和原始输入做残差连接,再进行归一化。
以 Pre-LN 风格为例:
X_1 = X + Attention(RMSNorm(X))
以 Post-LN 风格为例:
X_1 = LayerNorm(X + Attention(X))
具体顺序因模型而异。
第十一步:进入 FFN
然后进入 FFN:
X_2 = X_1 + FFN(RMSNorm(X_1))
FFN 会对每个 token 的表示做进一步非线性加工。
可以理解为:
Attention 像查资料。
FFN 像自己消化总结。
第十二步:经过多层 Transformer
注意力、FFN、残差、归一化组成一个 Transformer block。
实际模型会堆叠很多层,比如:
32 层
40 层
80 层
经过多层之后,每个位置的向量都会包含更丰富的上下文信息。
第十三步:模型预测下一个 token
最后一层输出的向量经过 LM Head:
logits = h_last · W_LM_Head
再经过 softmax:
probs = softmax(logits)
如果输入是:
我 吃
模型需要预测下一个 token。
它可能输出:
|
token |
概率 |
|---|---|
|
鱼 |
0.42 |
|
饭 |
0.25 |
|
面 |
0.12 |
|
苹果 |
0.03 |
|
... |
... |
如果生成策略选择概率最高的 token,就会输出:
鱼
最终得到:
我吃鱼
23. 给 MLOps 学习者的下一步
23.1 主流推理框架选型指南
学习原理之后,最终要落到部署和优化。
常见主流推理框架包括:
vLLM
TGI,Text Generation Inference
SGLang
TensorRT-LLM
它们的侧重点不同。
vLLM
核心优势:
PagedAttention
高吞吐
显存利用率高
适合通用在线推理服务
适合场景:
高并发 chat 服务
通用文本生成
对吞吐要求高的场景
TGI
核心优势:
生产功能完整
监控和部署生态成熟
支持多种量化和 LoRA
适合企业级部署
适合场景:
企业生产环境
需要较完整服务能力
需要 HuggingFace 生态集成
SGLang
核心优势:
结构化输出强
适合 Agent、tool calling、JSON schema
RadixAttention 对共享前缀和多轮对话友好
适合场景:
Agent 系统
工具调用
结构化生成
复杂 prompt 复用
TensorRT-LLM
核心优势:
NVIDIA GPU 上深度优化
kernel 级别优化多
适合追求极致性能
适合场景:
对延迟和吞吐要求非常高
团队具备较强 CUDA / 推理引擎能力
MLOps 视角:
不要只问“哪个框架最快”。
要结合业务场景看:是否需要长上下文 是否需要高并发 是否需要结构化输出 是否需要 tool calling 是否需要多 LoRA 热切换 是否需要 prefix caching GPU 型号是什么 显存大小是多少 延迟指标是 TTFT 还是 TPOT 运维团队是否能维护复杂引擎选型不是技术炫技,而是业务约束下的工程折中。
另外,推理框架生态更新很快,最终以当前版本功能和实测 benchmark 为准。
23.2 实战实验室:从原理到工程
建议你按顺序做下面几个实验。
实验 1:读取模型配置,理解模型结构
目标:
学会看 config.json。
任务:
找一个开源模型,例如 Qwen、LLaMA、Mistral 系列。
找出以下字段:
hidden_size
num_hidden_layers
num_attention_heads
num_key_value_heads
intermediate_size
vocab_size
max_position_embeddings
rope_theta
rope_scaling
tie_word_embeddings
torch_dtype
然后回答:
这个模型有多少层?
主维度是多少?
每个 head 维度是多少?
KV Cache 用几个 head?
FFN 中间维度是多少?
词表大小是多少?
是否绑定 embedding 和 LM Head?
实验 2:手工估算 KV Cache
目标:
掌握推理显存大头。
任务:
假设:
num_layers = 32
num_kv_heads = 8
head_dim = 128
seq_len = 8192
dtype = BF16
计算单条请求的 KV Cache 显存。
公式:
KV Cache
= 2 × num_layers × num_kv_heads × head_dim × seq_len × bytes
然后把 seq_len 改成:
4096
8192
32768
131072
观察显存变化。
参考结果:
4096 ≈ 0.5 GB
8192 ≈ 1 GB
32768 ≈ 4 GB
131072 ≈ 16 GB
实验 3:用 vLLM 部署一个模型
目标:
理解推理服务启动参数。
重点观察:
max_model_len
tensor_parallel_size
gpu_memory_utilization
max_num_seqs
enable_prefix_caching
dtype
quantization
记录:
启动显存占用
首 token 延迟 TTFT
生成速度 tokens/s
并发增加时吞吐变化
实验 4:对比 Prefill 和 Decode
目标:
理解推理两阶段瓶颈。
方法:
构造不同 prompt 长度:
短 prompt,长输出
长 prompt,短输出
长 prompt,长输出
观察:
TTFT 是否明显变长?
TPOT 是否稳定?
GPU 利用率如何?
显存占用如何变化?
实验 5:LoRA 微调显存对比
目标:
理解参数高效微调。
任务:
用同一模型分别做:
全参数训练
LoRA
QLoRA
对比:
显存占用
训练速度
可训练参数量
checkpoint 大小
部署复杂度
这些实验做完后,你会从“知道原理”进入“能做工程落地”。
24. MLOps 部署前检查清单
24.1 模型配置检查
hidden_size
num_hidden_layers
num_attention_heads
num_key_value_heads
head_dim
intermediate_size
vocab_size
max_position_embeddings
rope_scaling
tie_word_embeddings
24.2 显存检查
模型权重显存
KV Cache 显存
激活值显存
临时缓冲
并发请求下的峰值显存
长上下文下的峰值显存
24.3 推理服务检查
TTFT
TPOT
tokens/s
max_batch_size
max_model_len
gpu_memory_utilization
是否开启 prefix caching
是否开启 continuous batching
是否使用 PagedAttention
是否使用量化
24.4 Tokenizer 检查
vocab_size
special tokens
chat_template
stop tokens
是否支持 tool calling
是否支持多语言
是否支持代码
24.5 长文本检查
训练长度是多少
推理长度是多少
是否配置 rope_scaling
是否做过长文本评测
是否存在注意力退化
24.6 训练 / 微调检查
是否全参数训练
是否 LoRA
是否 QLoRA
优化器状态显存
激活值显存
梯度累积
序列长度
batch size
是否 gradient checkpointing
只要每次部署模型前过一遍这个清单,很多显存 OOM、效果异常、无法停止、长文本退化问题,都可以提前发现。
最后一句话
大模型就是一个 “预测下一个 token” 的函数:
把文本变成向量,
经过几十层注意力和前馈网络加工,
输出词表上的概率分布,
再选出或采样出最可能的下一个 token。
所有参数,包括:
embedding
Q/K/V
W_O
FFN
归一化参数
LM Head
都是通过海量文本上的“预测下一个 token”任务训练出来的。
更多推荐
所有评论(0)