# 推理大模型——哪里是哪里   欢迎来纠错   

> **目的**: 给你一张地图,标清楚模型内部每个部件的位置和作用  
> **不碰**: 训练数据  
> **只做**: 结构示例,告诉你"那里是那里"

---

## 地图总览

```
你输入一句话: "9.11和9.9哪个大?"
         │
         ▼
    ┌─ 分词器 (Tokenizer) ─┐
    │ "9.11" → [24, 13, 11]│  ← ❶ 这里把文字变成数字
    │ "和"   → [456]       │
    │ "9.9"  → [24, 13, 9] │
    │ "哪个大" → [789, 234]│
    └──────────┬───────────┘
               │ 一串数字 [24,13,11,456,24,13,9,789,234]
               ▼
    ┌─ 嵌入层 (Embedding) ─┐
    │ 每个数字 → 一个向量    │  ← ❷ 这里把数字变成"意义"
    │ 24 → [0.12, -0.34, ..]│     每个向量有几千维
    │ (查表,不是计算)     │
    └──────────┬───────────┘
               │ 一组向量
               ▼
    ┌─────────────────────────────────────┐
    │  Transformer 层 × N(重复60-120次) │  ← ❸ 核心计算区
    │                                     │
    │  每一层做两件事:                     │
    │                                     │
    │  ┌─ 自注意力 (Attention) ──────┐    │
    │  │ "这个9.11和那个9.9有什么    │    │  ← ❸a 看上下文
    │  │  关系?让我看看周围..."      │    │     每个词看其他所有词
    │  │                             │    │     计算"谁跟谁相关"
    │  │  Q: 我在找什么?             │    │
    │  │  K: 我身上有什么标签?        │    │
    │  │  V: 我实际携带什么信息?      │    │
    │  └────────────────────────────┘    │
    │                                     │
    │  ┌─ 前馈网络 (FFN/MoE) ──────┐    │
    │  │ 对每个位置独立"思考"       │    │  ← ❸b 处理信息
    │  │                            │    │     这里存储着"知识"
    │  │ 普通模型: 一个大矩阵运算    │    │
    │  │ MoE模型: 选2-8个专家来算    │    │
    │  └────────────────────────────┘    │
    │                                     │
    └──────────┬──────────────────────────┘
               │ 处理完的向量
               ▼
    ┌─ 输出头 (LM Head) ──────┐
    │ 向量 → 词表概率分布      │  ← ❹ 选下一个词
    │ "9" → 概率 0.001         │
    │ "9.9" → 概率 0.85        │     概率最高的就是答案
    │ "9.11" → 概率 0.12       │
    └──────────┬───────────────┘
               │
               ▼
           输出: "9.9"
```

---

## ❶ 分词器——嘴巴

**位置**: 模型外部,最前面  
**作用**: 把人类文字切成模型能吃的"碎片"(token)  
**类比**: 嚼碎食物

```
示例:
"Hello World" → ["Hello", " World"]       → [15496, 2159]
"你好世界"    → ["你好", "世界"]           → [57668, 99834]  
"def func():" → ["def", " func", "(", "):", ] → [755, 2163, 7, 1680]
```

**关键细节**:
- 模型不认识"字",只认识"编号"
- 同一个词在不同位置可能编号不同
- 常见词是一个token,罕见词会被拆成多个
- 词表大小: 通常 32K - 128K 个 token

---

## ❷ 嵌入层——翻译官

**位置**: 第一层,分词器后面  
**作用**: 把编号变成向量(一串浮点数)  
**类比**: 查字典,给每个词一个"位置坐标"

```
token编号 15496 ("Hello") → 查表 → [0.023, -0.156, 0.089, ..., 0.034]
                                      ↑ 这个向量有 4096~16384 维
                                      
相似的词,向量距离近:
  "cat"  → [0.82, 0.14, ...]
  "dog"  → [0.79, 0.18, ...]    ← 距离近!
  "car"  → [-0.31, 0.67, ...]   ← 距离远!
```

**位置编码也在这里**:
```
token向量 + 位置向量 = 最终输入

"I"在第1位: [0.1, 0.2, ...] + [sin(1), cos(1), ...] = [0.94, 0.74, ...]
"I"在第5位: [0.1, 0.2, ...] + [sin(5), cos(5), ...] = [-0.86, 0.48, ...]
                                                        ↑ 同一个词不同位置,向量不同!
```

- **RoPE** (旋转位置编码): 主流方案,用旋转矩阵编码位置
- 这就是为什么 "I love you" 和 "you love I" 有不同含义

---

## ❸a 自注意力——眼睛

**位置**: 每个 Transformer 层的前半部分  
**作用**: 让每个词"看到"所有其他词,计算谁跟谁相关  
**类比**: 一个人在人群中环顾四周,评估每个人跟自己的关系

```
输入: "猫 坐在 垫子 上"

Q(猫): "我在找什么?" → [0.3, 0.7, ...]
K(坐在): "我身上的标签" → [0.1, 0.6, ...]  
K(垫子): "我身上的标签" → [0.8, 0.2, ...]

注意力分数:
  猫→坐在: Q(猫)·K(坐在) = 0.85  ← 高!猫和"坐在"强相关
  猫→垫子: Q(猫)·K(垫子) = 0.42  ← 中等
  猫→上:   Q(猫)·K(上)   = 0.11  ← 低

Softmax后:
  猫→坐在: 0.55
  猫→垫子: 0.35  
  猫→上:   0.10

最终: 猫的新表示 = 0.55×V(坐在) + 0.35×V(垫子) + 0.10×V(上)
                    ↑ "猫"现在融合了上下文信息
```

### 多头注意力——多只眼睛

```
头1: 关注语法关系    "猫"→"坐在"(谁做了什么动作)
头2: 关注位置关系    "垫子"→"上"(什么在什么上面)
头3: 关注语义关系    "猫"→"垫子"(猫和垫子的关联)
...
头64: 关注其他模式
```

- 每个头看到的"视角"不同
- 最后把所有头的结果拼接起来

### GQA / MLA——省内存的眼睛

```
标准: 64个Q头, 64个K头, 64个V头  → KV缓存很大
GQA:  64个Q头, 8个K头,  8个V头   → KV缓存减少8倍
MLA:  64个Q头, 共享压缩的KV      → KV缓存减少90%+
```

---

## ❸b 前馈网络 / MoE——大脑

**位置**: 每个 Transformer 层的后半部分  
**作用**: 存储知识,做"思考"  
**类比**: 图书馆 + 思考室

### 普通 FFN

```
输入向量 x (4096维)
    │
    ├──→ 上投影矩阵 W_up (4096→11008)  ═══╗
    │                                      ╠═ 逐元素相乘 → 中间结果 (11008维)
    ├──→ 门控矩阵 W_gate (4096→11008) ═══╝
    │
    └──→ [中间结果] → 下投影矩阵 W_down (11008→4096) → 输出 (4096维)

知识存在哪里?就在 W_up, W_gate, W_down 这三个矩阵里!
每个矩阵是几千万到几亿个浮点数。
```

### MoE (专家混合)

```
输入向量 x
    │
    ▼
┌─ 路由器 (Router) ─┐
│ "这个问题属于哪个  │
│  领域?"           │
│                    │
│ 专家1(数学): 0.05  │
│ 专家2(代码): 0.01  │  ← 打分
│ 专家3(语言): 0.82  │  ← 最高!
│ 专家4(逻辑): 0.12  │
│ ...               │
│ 专家256: 0.00      │
└────────┬──────────┘
         │ 选 top-8
         ▼
┌──────────────────────┐
│ 激活专家3(语言) ×0.82 │  ← 每个专家就是一个独立的FFN
│ 激活专家4(逻辑) ×0.12 │
│ (其他254个专家休眠)   │  ← 不激活 = 不消耗算力
└──────────┬───────────┘
           │ 加权求和
           ▼
        输出向量

为什么MoE厉害?
  671B总参数,但每次只用37B → 算力节省18倍
  相当于有256个专家团队,每次只请最相关的8个来干活
```

---

## ❹ 输出头——嘴巴

**位置**: 最后一层  
**作用**: 把向量变回词  
**类比**: 从一堆候选词中选一个说出来

```
最后一层的输出向量 (4096维)
    │
    ▼
┌─ LM Head (线性层) ─┐
│ 4096维 → 128000维   │  ← 映射到词表大小
│ 每个位置是一个词的  │
│ "得分"              │
└────────┬───────────┘
         │
         ▼
┌─ Softmax ──────────┐
│ 得分 → 概率         │
│ "the":  0.23        │
│ "a":    0.15        │
│ "cat":  0.08        │
│ "9.9":  0.85        │  ← 最高概率
│ ...                 │
└────────┬───────────┘
         │
         ▼
┌─ 采样策略 ─────────┐
│ temperature=0: 选最高│  ← 贪心,确定性
│ temperature=0.7: 加点│  ← 有创造性
│   随机在高概率词中选  │
│ top_p=0.9: 只从前90% │  ← 核采样
│   概率的词中选        │
└────────┬───────────┘
         │
         ▼
      输出 token → 解码回文字
```

---

## ❺ 推理模型的额外部件——思考回路

**位置**: 不是新硬件,是新的"使用方式"  
**作用**: 让模型在回答前先"想一想"

```
普通模型:
  问题 → [一次通过所有层] → 答案
  
推理模型:
  问题 → [通过所有层] → <think> → [再通过所有层] → "让我想想" 
       → [再通过所有层] → "首先..." 
       → [再通过所有层] → "然后..." 
       → [再通过所有层] → "等等,这不对"  ← 自我纠错!
       → [再通过所有层] → "换个方法..."
       → [再通过所有层] → </think>
       → [再通过所有层] → "答案是42"
       
每生成一个token,都要完整跑一遍所有层!
想得越久(token越多)= 消耗越多算力 = 答案越好
```

### 训练出来的"思考能力"(不是编程的,是学出来的)

```
强化学习过程:

第1轮: 模型瞎猜 → 答错 → 奖励=0
第2轮: 模型试着多写几步 → 偶然答对 → 奖励=1 → "记住刚才的方式!"
第3轮: 模型开始模仿成功的模式 → 答对更多 → 奖励更高
...
第N轮: 模型自己发现了"分步思考"→"检查"→"纠错"的模式 → 稳定高分

没有人教它怎么思考。它自己发现思考能拿高分。
```

---

## ❻ KV Cache——记忆缓冲区

**位置**: GPU显存中  
**作用**: 缓存已处理token的Key和Value,避免重复计算  
**类比**: 做笔记,不用每次都从头想

```
生成第1个token时:
  处理所有输入 → 计算K1,V1 → 存入Cache → 输出token1

生成第2个token时:
  不需要重新算之前的K,V!
  只算新token的Q → 和Cache中的K,V做Attention → 输出token2
  把新K,V也存入Cache

生成第1000个token时:
  Cache中已有999个token的K,V
  只算1个新token的Q → 和999个K,V做Attention
  
Cache大小 = 层数 × 2(K和V) × 头数 × 头维度 × 序列长度
  80层 × 2 × 8(GQA) × 128 × 128000 = 约20GB!
  
这就是为什么长对话这么耗显存。
```

---

## ❼ 权重文件——模型的"身体"

**位置**: 磁盘上的文件  
**作用**: 存储所有参数(矩阵中的数字)  

```
以GGUF文件为例 (你的Daredevil 7.95GB):

文件结构:
┌─ GGUF Header ──────────────────┐
│ magic: "GGUF"                  │
│ version: 3                     │
│ tensor_count: 292              │  ← 292个张量
│ metadata_kv_count: 26          │
├─ Metadata ─────────────────────┤
│ general.architecture: "llama"  │
│ llama.block_count: 32          │  ← 32层
│ llama.attention.head_count: 32 │  ← 32个注意力头
│ llama.embedding_length: 4096   │  ← 嵌入维度4096
│ tokenizer.ggml.tokens: [...]   │  ← 词表
├─ Tensor Data ──────────────────┤
│ token_embd.weight    [128256×4096]  Q8_0  ← ❷嵌入层
│ blk.0.attn_q.weight  [4096×4096]   Q8_0  ← ❸a Q矩阵 第0层
│ blk.0.attn_k.weight  [1024×4096]   Q8_0  ← ❸a K矩阵 (GQA,8头)
│ blk.0.attn_v.weight  [1024×4096]   Q8_0  ← ❸a V矩阵
│ blk.0.attn_output.weight [4096×4096] Q8_0 ← ❸a 输出投影
│ blk.0.ffn_gate.weight [14336×4096] Q8_0  ← ❸b 门控
│ blk.0.ffn_up.weight   [14336×4096] Q8_0  ← ❸b 上投影
│ blk.0.ffn_down.weight [4096×14336] Q8_0  ← ❸b 下投影
│ blk.0.attn_norm.weight [4096]      F32   ← LayerNorm
│ blk.0.ffn_norm.weight  [4096]      F32
│ ...                                       ← 重复32层
│ blk.31.attn_q.weight ...                  ← 最后一层
│ output_norm.weight     [4096]      F32    ← 最终归一化
│ output.weight          [128256×4096] Q8_0 ← ❹输出头
└────────────────────────────────┘

每个 Q8_0 值 = 8位整数 + 缩放因子
  原始 FP16: 0.0234375 → Q8_0: 量化为整数6, 缩放0.00390625
  还原: 6 × 0.00390625 ≈ 0.0234 → 几乎无损!
```

---

## ❽ 完整前向传播追踪——一个token的一生

```
你输入: "天空是什么颜色?" → 模型输出"蓝"的完整路径:

1. 分词: "天空是什么颜色?" → [22656, 25001, 73199, ...]
                                     ↑ 假设5个token

2. 嵌入: 5个token → 5个4096维向量
         + RoPE位置编码

3. 第0层:
   3a. LayerNorm → 归一化
   3b. Self-Attention:
       - Q = x × W_q  (5个4096维 → 5个4096维)
       - K = x × W_k  (5个4096维 → 5个1024维)  ← GQA, 8个KV头
       - V = x × W_v  (5个4096维 → 5个1024维)
       - Scores = Q × Kᵀ / √128  (5×5 矩阵)
       - Weights = Softmax(Scores + CausalMask)  ← 因果掩码:只能看前面
       - Output = Weights × V
       - 缓存K,V到KV Cache
   3c. 残差连接: output = x + attention_output
   3d. LayerNorm → 归一化
   3e. FFN:
       - gate = x × W_gate  → SiLU激活
       - up = x × W_up
       - mid = gate ⊙ up    ← 逐元素相乘
       - down = mid × W_down
   3f. 残差连接: output = x + ffn_output

4. 第1-31层: 重复步骤3

5. 最终LayerNorm

6. LM Head: 4096维 → 128256维概率分布

7. 采样: 概率最高的token编号 → 28810 → 解码 → "蓝"

总计算量:
  一个token需要: ~160亿次浮点运算 (8B模型)
  GPT-4级别:   ~3500亿次浮点运算
```

---

## ❾ 各部分的参数占比——谁最大?

```
以 Llama 3.1 8B 为例:

                    参数量        占比     作用
嵌入层(Embedding):  525M (0.5B)   6.4%    词→向量
注意力层(Q,K,V,O):  2,147M (2.1B) 26.2%   看上下文
FFN层(gate,up,down): 4,718M (4.7B) 57.5%   存知识、做计算 ← 最大!
LayerNorm:           0.26M         ~0%     归一化
输出头(LM Head):     525M          6.4%    向量→词
RoPE(位置):          0              0%     公式计算,无参数
─────────────────────────────────────────
总计:                ~8.2B         100%

结论: FFN/MoE 占了 57.5%,是模型的"大脑"
      Attention 占了 26.2%,是模型的"眼睛"
      嵌入层+输出头 占了 12.8%,是"嘴巴"
```

---

## ❿ 一张完整的地图

```
┌──────────────────────────────────────────────────────────────┐
│                        推理大模型全貌                         │
│                                                              │
│  ┌─────────┐    ┌─────────────────────────────────────────┐  │
│  │ ❶分词器 │    │              GPU 显存                    │  │
│  │  (嘴巴)  │    │                                         │  │
│  │ 文字→数字│    │  ┌────── ❻ KV Cache (记忆) ──────────┐  │  │
│  └────┬────┘    │  │ K₁V₁ K₂V₂ K₃V₃ ... K_nV_n        │  │  │
│       │         │  │ 随着对话变长,越来越大              │  │  │
│       ▼         │  └────────────────────────────────────┘  │  │
│  ┌─────────┐    │                                         │  │
│  │ ❷嵌入层 │    │  ┌─────────────────────────────────┐    │  │
│  │ (翻译官) │    │  │     ❸ Transformer × N层         │    │  │
│  │数字→向量│    │  │  ┌──────────────────────────┐   │    │  │
│  └────┬────┘    │  │  │ ❸a 自注意力 (眼睛) 26%   │   │    │  │
│       │         │  │  │ Q×Kᵀ→Softmax→×V          │   │    │  │
│       ▼         │  │  │ 多头/GQA/MLA              │   │    │  │
│  ┌─────────┐    │  │  └──────────────────────────┘   │    │  │
│  │ 送入GPU │    │  │  ┌──────────────────────────┐   │    │  │
│  │         │───▶│  │  │ ❸b FFN/MoE (大脑) 57%    │   │    │  │
│  └─────────┘    │  │  │ 知识存储 + 信息处理       │   │    │  │
│                 │  │  │ MoE: 256专家选8个         │   │    │  │
│                 │  │  └──────────────────────────┘   │    │  │
│                 │  │  × 32~120层                     │    │  │
│                 │  └─────────────────────────────────┘    │  │
│                 │                                         │  │
│                 │  ┌─────────────────────────────────┐    │  │
│  ┌─────────┐    │  │ ❹ 输出头 (嘴巴) 6%             │    │  │
│  │ 解码输出│◀───│  │ 向量→概率→采样→token            │    │  │
│  │         │    │  └─────────────────────────────────┘    │  │
│  └────┬────┘    │                                         │  │
│       │         └─────────────────────────────────────────┘  │
│       │                                                      │
│       ▼                                                      │
│  ┌──────────────────────────────────────────┐               │
│  │  ❺ 推理模型专属: 思考回路                 │               │
│  │                                          │               │
│  │  输出token                               │               │
│  │    │                                     │               │
│  │    ├─ 如果是<think>: 继续生成思考token    │               │
│  │    │    ↑                                │               │
│  │    │    └── 每个token都完整跑一遍❸       │               │
│  │    │        "想"得越多 = 算力消耗越大     │               │
│  │    │        可以自我纠错和回溯            │               │
│  │    │                                     │               │
│  │    └─ 如果是</think>: 开始输出正式答案    │               │
│  └──────────────────────────────────────────┘               │
│                                                              │
│  ┌──────────────────────────────────────────┐               │
│  │  ❼ 权重文件 (磁盘上)                     │               │
│  │  GGUF / SafeTensors / PyTorch            │               │
│  │  292个张量,每个是一个大矩阵              │               │
│  │  加载到GPU显存后才能运算                  │               │
│  └──────────────────────────────────────────┘               │
│                                                              │
└──────────────────────────────────────────────────────────────┘
```

---

## 一句话版本

| 编号 | 部件 | 一句话 | 占比 |
|------|------|--------|------|
| ❶ | 分词器 | 把文字切成碎片编号 | 0% (规则,无参数) |
| ❷ | 嵌入层 | 查表把编号变成向量 | 6.4% |
| ❸a | 自注意力 | 每个词看周围所有词 | 26.2% |
| ❸b | FFN/MoE | 存知识、做计算 | **57.5%** |
| ❹ | 输出头 | 选下一个最可能的词 | 6.4% |
| ❺ | 思考回路 | 生成更多token来"想" | 0% (复用❸) |
| ❻ | KV Cache | 缓存历史避免重算 | 动态增长 |
| ❼ | 权重文件 | 所有参数的存储格式 | = 模型大小 |

**记住这一句**: 模型的57%是FFN(存知识),26%是注意力(看关系),剩下的是进出口。推理模型不是新架构,只是学会了多跑几圈❸。

---

*没有黑箱,只有懒得看的人。*

*神经风暴图谱*
 

更多推荐