手撕LLM(Transformer)
说明:本文是 Transformer / LLM 架构的学习与代码复现笔记。内容与代码实践参考了 Bilibili 视频 《手撕一个大模型看这个视频就够了【代码精读】》;本文在此基础上按个人学习逻辑进行了整理,并针对 Hexo Blog 的阅读体验做了排版适配。
本文从代码出发,完整梳理 Transformer 的基础架构、核心模块以及大模型从训练到推理的基本流程。重点不是只会调用现成模型,而是把 Tokenizer、Embedding、Position Encoding、Multi-Head Attention、FFN、Normalization 和 Decoder 串起来,理解一个自回归大模型究竟是怎样工作的。
大模型生命周期(概念图)
1 | |
/img/remote-3276f7c6ac29.jpeg)
High Level Insight
- 算法(大模型架构):完全从零手撕大模型
- 数据(训练数据、评测数据):完全从零评测大模型
- 算力(基础设施建设,即AI Infra):完全从零训练大模型、完全从零部署大模型
pip install torch modelscope tokenizers
Step1 Transformer架构总览(Overview)
Transformer 架构总览
1 | |
GPT 类大模型通常采用 Decoder-only 架构;T5 则是典型的 Encoder-Decoder 架构。
/img/remote-6958b4ed2b83.png)
1 | |
运行输出(点击展开)
1 | |
1 | |
运行输出:
1 | |
Step2 实现Transformer大类(Building Blocks)
Decoder-only Transformer 的核心数据流
1 | |
/img/remote-cab298451c25.jpeg)
1 | |
运行输出(点击展开)
1 | |
1 | |
运行输出:
1 | |
1 | |
运行输出:
1 | |
1 | |
运行输出:
1 | |
1 | |
运行输出:
1 | |
1 | |
Step3 实现Transformer各个模块(Coarse to Fine)
Module1 分词器(Tokenizer)
1 | |
运行输出:
✅ 分词器已保存到 my_tokenizer.json,词表大小: 481
注意:**ByteLevel** 预分词器会将 UTF-8 字节 映射到 可打印的 Unicode 字符。
| 中文 | UTF-8 字节 | ByteLevel 映射 |
|---|---|---|
| 是 | **0xE6 0x98 0xAF** |
**æ**``**ĺ**``**¯**→ **æĺ¯** |
| 的 | **0xE7 0x9A 0x84** |
**ç**``**ļ**``**Ħ**→ **çļĦ** |
| 学习 | … | **åŃ¦ä¹ł** |
| 神经 | … | **ç¥ŀç»ı** |
tokenizer.json 中: “æĺ¯” → 代表中文 “是” “çļĦ” → 代表中文 “的” “åŃ¦ä¹ł” → 代表中文 “学习”
1 | |
运行输出:
1 | |
Module2 词嵌入(Word Token Embedding)
1 | |
1 | |
运行输出:
输入: torch.Size([2, 10]) -> 输出: torch.Size([2, 10, 256])
Module3 位置嵌入(Word Position Embedding)
$$PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d_{model}}}\right)$$
$$PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d_{model}}}\right)$$
其中$pos$为位置索引(0, 1, 2, …),$i$为维度索引(0, 1, 2, …, d_model/2)
1 | |
1 | |
运行输出:
位置编码后: torch.Size([2, 10, 256])
Module4 多头注意力机制(Multi-Head Attention)
1 | |
1 | |
运行输出:
注意力输出: torch.Size([2, 10, 256])
Module5 前馈神经网络(Feed Forward Network)
1 | |
1 | |
运行输出:
FFN输出: torch.Size([2, 10, 256])
Module6 层归一化(Layer Normalization)
LayerNorm$$\text{LayerNorm}(x) = \gamma \odot \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} + \beta$$其中:
- $\mu = \frac{1}{H} \sum_{i=1}^{H} x_i$ (均值)
- $\sigma^2 = \frac{1}{H} \sum_{i=1}^{H} (x_i - \mu)^2$ (方差)
RMSNorm$$\text{RMSNorm}(x) = \frac{x}{\text{RMS}(x)} \cdot \gamma$$$$\text{RMS}(x) = \sqrt{\frac{1}{H} \sum_{i=1}^{H} x_i^2 + \epsilon}$$
1 | |
1 | |
运行输出:
归一化输出: torch.Size([2, 10, 256])
1 | |
运行输出:
配置: LMConfig(vocab_size=6400, hidden_size=512, num_layers=8, num_heads=8, intermediate_size=2048, max_seq_len=512, dropout=0.1)
1 | |
运行输出:
模型参数量: 2,229,760
Step4 训练一个属于你自己的大模型
1 构造数据集(Data)
https://www.modelscope.cn/datasets/gongjy/minimind_dataset
预训练阶段数据集、有监督微调数据集和强化学习数据集
2 预训练阶段(Pretraining)
/img/remote-ce8e26fd9689.jpeg)
1 | |
3 有监督微调(Supervised Fine Tuning)
用对话数据集的形式,让大模型学会遵循指令和回答问题
4 强化学习(Reinforcement Learning)
1 | |
5 模型部署(Inference)
1 | |
主要参考资料如下:
https://github.com/karpathy/nanoGPT
https://github.com/karpathy/nanochat