前置知识

阅读本文前,建议先了解:


一句话总结

文本生成模型 = Transformer 架构 + 海量预训练 + 对齐调优 + 推理加速

flowchart TD
    A[文本生成模型] --> B[核心架构]
    A --> C[模型结构]
    A --> D[训练流程]
    A --> E[推理优化]
    A --> F[长上下文处理]

    B --> B1[Self-Attention]
    B --> B2[多头机制]
    B --> B3[RoPE 位置编码]

    C --> C1[稠密模型]
    C --> C2[MoE 稀疏模型]

    D --> D1[预训练]
    D --> D2[SFT 微调]
    D --> D3[RLHF/DPO 对齐]

    E --> E1[KV Cache]
    E --> E2[量化 INT4/8]
    E --> E3[推测解码]

    F --> F1[稀疏 Attention]
    F --> F2[位置插值]
    F --> F3[滑动窗口]

一、核心架构

1.1 自回归生成

LLM 做一件事:根据前面的文字,预测下一个字

输入:"今天天气很"
          ↓
模型计算所有可能下一个字的概率:
  好:45%
  不错:25%
  糟糕:15%
  一般:10%
  ...
          ↓
采样一个字输出:"好"
          ↓
新输入:"今天天气很好" → 继续预测下一个字

[!比喻] 自回归生成像什么? 就像接龙游戏——看到”床前明月”,你接”光”;看到”床前明月光”,你接”疑”……一句话就是这样接出来的。


1.2 Self-Attention:让每个字”看到”其他字

Transformer 之前用 RNN 处理序列,问题是记不住开头、无法并行

Self-Attention 让句子中的每个字同时”看到”所有其他字:

graph LR
    A[输入序列] --> B[Query 向量]
    A --> C[Key 向量]
    A --> D[Value 向量]

    B --> E[注意力分数计算]
    C --> E
    E --> F[Softmax 归一化]
    D --> G[加权求和]
    F --> G
    G --> H[输出表示]

QKV 通俗解释

  • Query(查询):我想知道什么
  • Key(键):我能提供什么信息
  • Value(值):我的实际内容
例子:"我喜欢吃苹果,因为它很甜"

处理"它"时:
- Query:"它"指代什么?
- Key:"苹果"说"我是水果"
- Value:"苹果"的实际含义

→ 注意力让"它"关注到"苹果",理解指代关系

1.3 多头注意力(Multi-Head Attention)

一个头只能捕捉一种关系,多个头并行捕捉不同类型:

graph TD
    A[输入] --> B[Head1: 语法关系]
    A --> C[Head2: 语义关系]
    A --> D[Head3: 指代关系]
    A --> E[Head4: 位置关系]

    B --> F[拼接 + 线性变换]
    C --> F
    D --> F
    E --> F
    F --> G[输出]

[!比喻] 多头注意力 就像一群人同时读一句话——有人关注语法,有人关注词义,有人关注指代。最后综合起来,理解更全面。


1.4 位置编码:RoPE

Transformer 没有顺序处理机制,需要位置编码告诉模型”谁在前、谁在后”。

2026 年主流用RoPE(Rotary Positional Embedding):

RoPE 核心思想:
- 把每个词的向量"旋转"一个角度
- 旋转角度 = 位置信息
- 相邻位置旋转角度相近,远距离差距大

好处:
- 外推性好:训练时没见过的长度,推理时也能处理
- 支持长上下文:128K、1M 甚至 10M Token

二、模型结构

2.1 稠密模型 vs 稀疏 MoE

传统稠密模型:
参数越多 → 计算量越大 → 推理越慢 → 成本越高

GPT-4(~1.8 万亿参数):
- 每次推理激活所有参数
- 需要大量 GPU 并行
- 成本极高($15-30 / 百万 Token)

MoE(Mixture of Experts)思路:只激活需要的部分


2.2 MoE 工作原理

graph TD
    A[输入 Token] --> B[路由器 Router]
    B --> C{选择专家}
    C -->|Top-2| D[专家 1]
    C -->|Top-2| E[专家 2]
    C --> F[专家 3 不激活]
    C --> G[专家 4 不激活]

    D --> H[加权输出]
    E --> H
    H --> I[最终输出]
GPT-5 MoE 架构示例:

总参数:1.8 万亿
专家数量:128 个
每次激活:2 个专家(约 300 亿参数)

输入:"写一个快速排序算法"
      ↓
路由器:代码任务 → 激活"代码专家 1"+"代码专家 2"
      ↓
输出:排序代码

输入:"写一篇春天的散文"
      ↓
路由器:文学创作 → 激活"文学专家 3"+"文学专家 5"
      ↓
输出:散文

2.3 MoE 关键概念对比

概念解释
总参数(Total Parameters)模型所有权重的数量
激活参数(Active Parameters)每次推理实际使用的参数
稀疏度(Sparsity)激活参数/总参数,越低越省算力
路由器(Router/Gate)决定激活哪些专家的网络

2.4 MoE 优势与代价

优势:
┌─────────────────────────────────────────┐
│  ✅ 参数量大:可以做到万亿级别          │
│  ✅ 推理成本低:只激活一小部分          │
│  ✅ 专业分工:不同专家擅长不同任务      │
└─────────────────────────────────────────┘

代价:
┌─────────────────────────────────────────┐
│  ⚠️ 训练复杂:需要额外训练路由器        │
│  ⚠️ 通信开销:分布式推理时需要协调      │
│  ⚠️ 负载不均衡:某些专家可能被过度使用  │
└─────────────────────────────────────────┘

三、训练流程

3.1 预训练:LLM 的”读书”阶段

预训练 = 让模型读海量文本,学会语言规律

数据源:
- 网页爬取(Common Crawl 等)
- 书籍(公版书 + 授权书)
- 维基百科
- 代码(GitHub 等)
- 论坛对话(Reddit、StackOverflow)

数据量:
- Llama 3:15 万亿 Token
- Qwen 2.5:18 万亿 Token
- GPT-4:约 13 万亿 Token(估计)

预训练任务:完形填空/下一个词预测

输入:"今天天气很____"
正确答案:"好"

模型预测:"好"(正确)→ 奖励
模型预测:"香蕉"(错误)→ 惩罚(调整参数)

重复数万亿次,模型学会语言规律

3.2 监督微调(SFT):让模型听懂指令

预训练后的模型会说话,但不会”听指令”。

SFT(Supervised Fine-Tuning):

准备指令 - 回答对:
  指令:"写一首关于春天的诗"
  回答:"春风拂面百花香,..."

训练:让模型学会按照指令格式回答

效果:模型听懂指令,但可能不够"人性化"

3.3 RLHF:让人类反馈优化模型

graph LR
    A[SFT 模型] --> B[生成多个回答]
    B --> C[人类标注员打分]
    C --> D[训练奖励模型]
    D --> E[PPO 优化策略]
    E --> F[对齐后的模型]

RLHF 三步走

  1. 收集偏好数据:同一个问题,生成两个回答,让人类标注哪个更好
  2. 训练奖励模型:让模型学会”人类喜欢什么样的回答”
  3. PPO 优化:用强化学习让模型最大化奖励模型的分数

3.4 DPO:RLHF 的替代方案

DPO(Direct Preference Optimization):

RLHF 的缺点:
- 需要额外训练奖励模型
- PPO 训练复杂,容易崩

DPO 的优点:
- 直接用偏好数据优化策略
- 训练稳定,效果好
- 2026 年主流方法

[!比喻] RLHF vs DPO

  • RLHF = 先培养一个”评委”(奖励模型),再让选手(语言模型)讨好评委
  • DPO = 直接告诉选手”这样的回答更好”,不需要中间商

四、推理优化

4.1 KV Cache:避免重复计算

问题:自回归生成时,之前的 Token 被重复计算。

第 1 步:输入"你" → 计算 Attention → 输出"好"
第 2 步:输入"你好" → 重新计算 Attention → 输出","
第 3 步:输入"你好," → 重新计算 Attention → 输出"请"

问题:"你"、"你好"的 Attention 被重复计算了!

KV Cache 解决

  • 缓存已计算的 Key 和 Value
  • 新 Token 只需要计算自己的部分
  • 速度提升 5-10 倍

4.2 量化:减少显存占用

精度 vs 内存:

FP16(半精度):每个参数 2 字节
  70B 模型 = 140GB 显存

INT8(8 比特量化):每个参数 1 字节
  70B 模型 = 70GB 显存
  精度损失 < 1%

INT4(4 比特量化):每个参数 0.5 字节
  70B 模型 = 35GB 显存
  精度损失 ~3-5%

2026 年主流:INT4 量化 + 反量化加速

4.3 推测解码:小模型草稿 + 大模型验证

graph LR
    A[小模型] --> B[生成草稿]
    B --> C[大模型验证]
    C --> D{接受?}
    D -->|是 | E[一次性输出多个 Token]
    D -->|否 | F[拒绝,重新生成]
推测解码思路:

小模型(如 Llama-3-8B)生成草稿:
  "今天天气很" → "好" → "," → "适合" → "出门"

大模型(如 Llama-3-70B)一次性验证:
  接受 3 个,拒绝 1 个

结果:4 步计算变成 2 步,速度约 2 倍提升

五、长上下文处理

5.1 为什么长上下文难

Attention 计算复杂度:O(n²)

1K Token:1M 次计算
128K Token:164 亿次计算(16000 倍)
1M Token:1 万亿次计算(100 万倍)

问题:
- 显存爆炸
- 计算时间过长
- 信息稀释(注意力分散)

5.2 2026 年主流方案

方案原理代表模型
稀疏 Attention只计算部分位置的注意力Llama 4
滑动窗口只关注最近的 N 个 TokenMistral
位置插值压缩长序列到训练范围Qwen 3.5
分层压缩把长文本分层摘要Kimi K2
混合方案多种技术组合Gemini 2.5

5.3 位置插值:从 32K 到 1M

训练时:模型见过的位置是 0, 1, 2, ..., 32768
推理时:要处理 0, 1, 2, ..., 1048576(1M)

做法:把长序列"压缩"进训练过的范围
       用插值法计算中间位置

这就像把一张小图放大——用插值算法"猜"出新像素的值

总结

mindmap
  root((文本生成技术))
    核心架构
      Transformer
      Self-Attention
      多头机制
      RoPE 位置编码
    模型结构
      稠密模型
      MoE 稀疏模型
    训练流程
      预训练
      SFT 指令微调
      RLHF/DPO 对齐
    推理优化
      KV Cache
      量化 INT4/INT8
      推测解码
    长上下文
      稀疏 Attention
      位置插值
      滑动窗口

延伸阅读