# 大语言模型算子详解：学术版 + 白话版

> **注！** 本文专业名词较多，对于各位同学我推荐先阅读白话版再阅读学术版。

---

## 📚 学习本文有什么用？

- 文章拆解到算子级别，有利于做模型部署/推理优化
- 有助于算法研究与模型设计
- 这是大模型 infra/算法岗的高频考点

---

# 第一部分：学术版

> 以 Qwen2.5-32B 大语言模型为例，将大语言模型的所有算子梳理一遍，并描述大模型推理的整个过程。

> **名词解释：**
> - **Qwen2.5-32B**：阿里巴巴通义千问团队开源的大语言模型，32B 表示 320 亿参数。"B" 是 Billion（十亿）的缩写
> - **算子梳理**：把模型推理涉及的每个计算步骤都列出来并解释
> - **推理的整个过程**：注意区分"训练"和"推理"。训练是模型学习的过程，推理是模型已经学好了，你给它输入，它给你输出的过程

---

大语言模型的底层算力，全部由算子承载。算子是模型推理/训练的最小执行单元，LLM 回答问题、学习知识，本质都是算子在做数学运算，没有算子就无法运行。

> **LLM 的最小执行单元** = 不可再拆分的运算步骤，如"两个矩阵相乘"就是 1 个算子。

## 一、整体流程概览

下图是完整流程：

![](https://com.miui.notes/note_image/59dd31e5e9566477ab18400de49530651908fe8b)

> ⚠️ 把图片下载下来！对着文字来读来看

其中：
- **B** 表示 Batch（批次）数，表示同时输入了多少个请求
- **S** 表示输入请求的 Sequence Length（序列长度）

> **名词解释：**
> - **Batch（批次）**：同时处理多少个请求。比如 Batch=4，就是同时给模型输入 4 句话
> - **Sequence Length（序列长度）**：每个请求有多少个 token。比如 "I like shanghai" 有 4 个 token（I、like、shanghai，加上可能的起始 token）

### 流程步骤

#### 步骤 1：输入 Prompt

一开始输入的是 B 个 Prompts，由一个个的 Token 组成，每个 Prompt 的 Token 个数为 S，比如 "I like shanghai" 等。

> **名词解释：**
> - **Prompt**：你给模型的输入提示/问题
> - **Token**：大模型处理文本的最小单位。注意不是按空格分词！比如 "shanghai" 可能是一个 token，但 "unbelievable" 可能被拆成 "un"、"believ"、"able" 三个 token。这取决于 Tokenizer 的训练方式

#### 步骤 2：Token 编码

经过 Tokenizer 的 Encode 操作会将输入的所有 Token 转换成 Token ID。Token ID 我们可以理解为这个 Token 在词表中的索引。Qwen2.5-32B 的词表大小为 152064。

> **名词解释：**
> - **Tokenizer（分词器）**：负责把人类文字转换成模型能理解的数字。它有两个方向：
>   - **Encode（编码）**：文本 → Token ID
>   - **Decode（解码）**：Token ID → 文本
> - **词表（Vocabulary）**：模型认识的所有 token 的集合。每个 token 对应一个唯一 ID
> - **152064**：Qwen2.5 的词表大小。这意味着模型输出时，每次要从 15 万多个候选中选下一个 token

#### 步骤 3：Embedding

经过 Embedding 操作之后得到输入每个 Token 的特征向量，这个向量是模型训练的结果。

> **名词解释：**
> - **Embedding（嵌入）**：把离散的 Token ID 转换成连续的向量
> - **为什么需要 Embedding？** 因为神经网络处理的是数字，而 Token ID 只是索引（比如 ID=5231），不代表语义。Embedding 把每个 token 映射到一个高维空间（这里是 5120 维），语义相近的 token 在这个空间中距离也近
> - **"模型训练的结果"**：这些向量不是随机生成的，是模型在训练过程中学习到的

#### 步骤 4：Transformer 处理

再经过如上图的 64 个 Layer 的 Transformer 模块的循环处理，后再做一次 RMSNorm 得到最终的 Hidden States。

> **名词解释：**
> - **64 个 Layer**：Qwen2.5-32B 有 64 层 Transformer。层数越多，模型越深，能力通常越强
> - **Transformer**：2017 年 Google 提出的架构，是当今大模型的基础。核心是自注意力机制（Self-Attention）
> - **Hidden States（隐藏状态）**：数据在模型内部流动时的中间表示。可以理解为模型对当前输入的"理解"
> - **RMSNorm**：一种归一化方法，后面会详细讲

#### 步骤 5：Token 预测

再经过 Token Linear（论文里面一般也叫：LM Head），得到每个输入请求的输出 Token ID。

> **名词解释：**
> - **Token Linear / LM Head（Language Model Head）**：最后一层线性变换，把 Hidden States 映射到词表空间（152064 维），得到每个候选 token 的分数

#### 步骤 6：Token 解码

再经过 Tokenizer 的 Decode 得到真正的 Token，这样就能完成整个 Prompt 输入再到 Token 输出的全流程推理。

> **名词解释：**
> - 这是**自回归生成**的过程——模型输出一个 token 后，把这个 token 拼回输入，再预测下一个 token，循环往复直到生成结束

---

## 二、算子详解

### Embedding 算子

如上图，Embedding 算子其实是一个 Gather 操作，他将输入的 Token ID 映射成一个 Embedding 的向量。

> **名词解释：**
> - **Gather 操作**：在编程中，Gather 就是"按索引取值"。比如词表是一个 [152064, 5120] 的矩阵，输入 Token ID=100，就取第 100 行的 5120 个数

**重要提醒：** 不是矩阵乘法！而是简单的查表（lookup）。但因为要处理大量 token，所以也需要优化。

**逻辑：** 遍历每个 Token ID，找到 Token ID 在 152064 中位置，取 Embedding Weight 中 Token ID 位置的 5120 个数据，复制到输出内存中。

> **名词解释：**
> - **Embedding Weight**：形状为 [词表大小, 隐藏维度] = [152064, 5120] 的参数矩阵。每个 token 被映射为一个 5120 维的向量

---

### RMSNorm 算子

取某个 Batch，某个请求的 5120 个特征向量，做 RMSNorm 操作。RMSNorm 公式为图中所示，d=5120。

> **名词解释：**
> - **Norm（归一化）**：让数据分布更稳定，帮助模型训练/推理更稳定
> - **RMSNorm（Root Mean Square Normalization）**：比 LayerNorm 更简单，去掉了均值计算，只保留方差归一化。做完图中公式的计算，得到输出的 5120 个数据 {y₀, y₁, ..., y₅₁₁₉}
> - **RMSNorm 是对每个 token 的向量单独做的，不是跨 batch 或跨 token**

---

### Multi Head Attention（多头注意力）

该模块的详细算子计算流程，见：[Attention 模块算子逻辑]()。

> **名词解释：**
> - **Multi-Head Attention（MHA）**：Transformer 的核心。把输入分成多组（头），每组独立计算注意力，最后拼接
> - **注意力机制**：计算 Query 和 Key 的相似度，决定 Value 的加权组合。通俗说就是"当前 token 应该关注哪些其他 token"
> - **GQA（Grouped Query Attention）**：Qwen2.5 用的优化版，多个 Query 头共享一组 Key/Value 头，减少内存和计算

---

### Add 算子

如上图，对于两个输入数据，对应 Batch、对应请求、对应位置的元素相加就是 Add 算子逻辑。

> **名词解释：**
> - 这就是**残差连接（Residual Connection）**：`output = F(x) + x`
> - **作用**：缓解梯度消失，让深层网络更容易训练。在 Transformer 中，每个子层（Attention/MLP）后都有 Add
> - **ResNet 网络就是残差链接**，Kimi 最新提出了残差注意力机制，这是最新热点

---

### MLP 算子

该模块的详细算子计算流程，见：[MoE 模块的算子逻辑]()，其中每个专家就是一个 MLP。

> **名词解释：**
> - **MLP（Multi-Layer Perceptron）**：多层感知机，即前馈神经网络。在 Transformer 中通常是两个线性层夹一个激活函数（如 SwiGLU）
> - **MoE（Mixture of Experts）**：混合专家模型。Qwen2.5-32B 不是纯 Dense 模型，而是把 MLP 替换成多个"专家"网络，每次只激活部分专家。这能在不增加推理成本的情况下扩大模型容量

---

### Token-Linear（LM-Head）算子

如上图，Token Linear 其实是一个矩阵乘，乘完之后得到每个请求的输出与词表中所有 Token 的近似程度。

> **名词解释：**
> - **矩阵乘法**：`[batch×seq_len, hidden_dim] × [hidden_dim, vocab_size]`
> - **输出形状**：`[batch×seq_len, 152064]`，即每个位置对每个 token 的"分数"
> - 这个过程我们可以理解为 Embedding 的逆向过程，因此有模型将 Embedding 权重与 Token Linear 权重共享
> - **权重共享**：输入 Embedding 和输出 LM Head 可以共用同一个权重矩阵。这是 GPT 系列的做法，减少参数量，且 empirically 效果不差

---

### Sample 模块：Softmax/Argmax

如上图，采样模块其实有挺多复杂操作，比如 Top-K、Top-P、惩罚项、温度等，后续做专题介绍。

> **名词解释：**
> - **Top-K**：只保留分数最高的 K 个候选，其余置零
> - **Top-P（Nucleus Sampling）**：保留累积概率达到 P 的最小集合
> - **Temperature（温度）**：控制分布的"尖锐"程度。T→0 时接近贪婪，T 大时更随机
> - **惩罚项**：比如重复惩罚，避免模型一直重复同一个词

#### 最简单的采样逻辑

这里介绍一种最简单的逻辑，让整个推理闭环：

1. Token-Linear 输出的是 Token 落在词表中所有 Token 位置的近似程度（一般叫 Logits）
   > **Logits**：神经网络的原始输出分数，未归一化，可正可负

2. 对其做 SoftMax 操作转换成概率，再取概率最大的 Token ID（索引），再去 Tokenizer Decode 就能得到最终的 Token
   > - **Softmax**：把 logits 转换成概率分布（0~1 之间，和为 1）
   > - **Argmax**：取最大值的索引。这是贪婪解码（Greedy Decoding），每次选概率最高的 token

3. 实际应用中还会用 Beam Search 等更复杂的解码策略

---

# 第二部分：白话版

## 核心概念

- **B** 就是 Batch 数，说白了就是"同一时间，有多少人在给这个模型发问题"
- **S** 就是输入请求的 Sequence Length，简单说就是"你发的那句话，被拆成了多少个最小的字或词块"

## 整体流程（白话版）

1. **输入问题**：一开始，模型会收到 B 个问题（也就是大家常说的 Prompt），每个问题都是由一个个最小的字或词块（Token）组成的，每个问题有多少个这样的小块，就是 S。比如 "I like shanghai" 这句话，就被拆成了 3 个这样的小块

2. **分词编码**：然后经过 Tokenizer（说白了就是分词、转码的工具）的 Encode（编码）操作，会把所有输入的字或词块（Token），都转换成一串数字编号（也就是 Token ID）。这个数字编号很好理解，就相当于这个字或词在模型"字典"里的页码，查这个页码就能找到对应的字或词。Qwen2.5-32B 的"字典"里，一共收录了 152064 个不同的字、词或符号

3. **理解语义**：再经过 Embedding（嵌入）操作，每个字或词块（Token）都会对应上一串数字（也就是语义向量）。这串数字不是随便来的，是模型之前经过大量训练学出来的，代表着这个字或词的意思，就相当于给每个字、每个词都贴了一个"意思标签"，让模型能看懂它

4. **深度处理**：接着，这串代表意思的数字，会经过 64 层 Transformer 模块——这个模块就相当于模型的"大脑"，会一层一层地琢磨、处理这些数字，把你的问题彻底看懂。处理完之后，再做一次 RMSNorm 操作，得到的就是模型"完全看懂你问题"后的结果（Hidden States）

5. **预测下一个字**：之后，再经过 Token Linear（论文里叫 LM Head，不用管这个名字，知道它是负责预测下一个字的就行），就能算出每个问题接下来最可能出现的字或词的数字编号（也就是输出 Token ID）

6. **生成回答**：最后，再经过 Tokenizer 的 Decode（解码）操作，把算出来的数字编号，再转成我们能看懂的文字，这样就完成了"你发问题→模型给回答"的整个过程

---

## 算子详解（白话版）

### A. Embedding 算子

就像上图显示的那样，Embedding 算子其实就是一个简单的"查表"操作，专业上叫 Gather，说白了就是查字典，它的作用就是把前面得到的数字编号（Token ID），转换成对应的、代表意思的数字串（语义向量）。

说得再简单点：**一个一个看每个数字编号（Token ID），找到它在模型"字典"（152064 个词）里的位置，然后从模型提前存好的"意思数字表"（Embedding Weight）里，把这个位置上的 5120 个数字，复制到指定的地方，这样就得到了这个字或词对应的、代表意思的数字串。**

---

### B. RMSNorm 算子

拿某个用户的问题对应的 5120 个代表意思的数字，做 RMSNorm 操作——说白了就是把这些数字调整得更均匀。RMSNorm 的公式就是上图里的，其中 d=5120。

具体怎么做呢？就是把这 5120 个数字，按照上图的公式算一遍，算完之后还是 5120 个数字。这么做的目的，就是让这些数字大小差不多，不会有的特别大、有的特别小，这样模型计算的时候才不会出问题，能稳定运行。

---

### C. Multi Head Attention

这个模块具体是怎么计算的（里面的算子怎么工作），大家可以去看：[Attention 模块算子逻辑 - 知乎]()，里面讲得很详细。

我简单跟大家补一句：这部分是模型最核心的"大脑"，主要作用就是看懂你问题的上下文——比如你说"他喜欢吃苹果，他也喜欢吃梨"，模型能知道两个"他"是同一个人；还能判断哪个词更重要，从好几个角度去理解你说的话。

---

### D. Add 算子

就像上图显示的那样，Add 算子特别简单，一点不复杂：有两串数字，这两串数字要对应好——同一个用户、同一个问题、同一位置的数字，一一对应加起来就行，比如第一串的第一个数字加第二串的第一个数字，第二个加第二个，以此类推。

---

### E. MLP 算子

这个模块具体是怎么计算的（里面的算子怎么工作），大家可以去看：[MoE 模块的算子逻辑 - 知乎]()，里面说的每个"小专家"（MoE 模块里的），其实就是一个 MLP。

我简单补一句：**MLP 的作用，就是把代表意思的数字串再加工一下，帮模型做逻辑推理。** 比如你说"我喜欢上海"，模型就能通过 MLP 琢磨出"上海是大城市，所以我可能也喜欢大城市"。

---

### F. Token-Linear（LM-Head）算子

就像上图显示的那样，Token Linear 其实就是做一次简单的数字矩阵相乘，算完之后，就能知道每个问题接下来的字，和模型"字典"里所有字、词的匹配程度（专业上叫 Logits，不用记这个名字）。

这个过程大家可以简单理解成，和前面的 Embedding 算子**反过来做**：
- Embedding 是把"文字"变成"代表意思的数字串"
- Token Linear 是把"代表意思的数字串"变成"和每个文字的匹配程度"

所以很多模型会把这两个步骤用到的"数字表"（权重）共用，这样能节省空间，让模型运行得更高效。

---

### G. Sample 模块：Softmax/Argmax

就像上图显示的那样，这个采样模块其实有不少复杂的操作，比如 Top-K、Top-P、重复惩罚、温度调节这些，这些我后面会专门写一篇文章跟大家讲。

这里先跟大家讲一个最简单的逻辑，帮大家搞明白，从"匹配程度"到"最终回答"，到底是怎么来的：

1. 前面我们说过，Token-Linear 算出来的，是"下一个字和模型字典里所有字、词的匹配程度"

2. 我们再做一次 SoftMax 操作，把这个匹配程度转换成 0 到 1 之间的概率（所有概率加起来刚好是 100%）

3. 然后挑出概率最大的那个字或词的数字编号（用 Argmax 操作，不用记名字，知道是挑概率最大的就行）

4. 再通过 Tokenizer 的 Decode 操作，把数字编号转换成我们能看懂的文字，这就是模型最终给你的回答了