导读:文本预处理与数据管道
核心:如何将原始文本转化为 LLM 能够理解的数学向量
在 LLM 的构建过程中,第一步不是编写模型架构,而是准备数据集。本章的目标是将像《裁决》(The Verdict)这样的短篇小说,逐步转化为深度学习模型可以处理的嵌入向量(Embedding Vectors)。
目录
- 1. LLM 的三个核心阶段
- 2. 数据源:公共领域文学作品
- 3. 分词:从文本 到 Tokenization
- 4. 词汇表与token ids (Vocabulary & Token IDs)
- 5. 数据采样与滑动窗口 (Sliding Window)
- 6. 嵌入向量层 (Embedding Layer)
- 🏗️ 全栈工程师实战清单 (Mac M4)
1. LLM 的三个核心阶段
Sebastian 明确了构建大模型的完整链路:
- 数据准备(本章重点):设置数据集、分词、编码。
- 预训练(Pre-training):在大规模数据上训练模型。
- 微调(Fine-tuning):在特定任务上对模型进行优化。
2. 数据源:公共领域文学作品
为了教学的简洁性和规避版权问题,本书使用了伊迪丝·沃顿(Edith Wharton)的短篇小说 《裁决》(The Verdict)。
- 仓库地址:rasbt/LLMs-from-scratch
- 本地下载:
- 你可以通过 Python 的
urllib.request直接从作者的 GitHub 原始路径获取the-verdict.txt。
- 你可以通过 Python 的
3. 分词:从文本 到 Tokenization
3.1 基础分词 (Regex)
分词是将连续的字符串拆解为更小的单位(Token)。
- 初步尝试:
- 通过简单的正则表达式(Regex)在空格处拆分。
- 优化方案:
- 为了处理标点符号,我们需要更复杂的正则,将逗号、句号等独立出来。
3.2 字节对编码 (BPE)
虽然正则分词简单,但无法处理“词汇表外(OOV)”词汇。书中引入了更高级的 BPE(Byte Pair Encoding) 算法:
- 核心优势:
- 即使遇到未知词(如罕见人名),它也能将其拆解为已知的子词(Subwords)或单个字母,永远不会出现
KeyError。
- 即使遇到未知词(如罕见人名),它也能将其拆解为已知的子词(Subwords)或单个字母,永远不会出现
- 推荐库:使用 OpenAI 开源的
tiktoken。- Macbook M4 提示:
tiktoken的核心是用Rust编写的,在你的 M4 芯片上运行速度极快。
- Macbook M4 提示:
pip install tiktoken
4. 词汇表与token ids (Vocabulary & Token IDs)
一旦有了分词列表,我们就需要建立词汇表(Vocabulary):
- 去重排序:提取所有唯一的token并按字母排序。
- 建立映射:给每个 token 分配一个唯一的整数索引(Token ID)。
- 特殊token:
<|endoftext|>:标记一个文档的结束,在拼接多篇文档时至关重要。<|unk|>:在简单分词器中标记未知词(BPE 中通常不需要)。
5. 数据采样与滑动窗口 (Sliding Window)
LLM 的训练本质上是预测下一个词。为了高效喂给模型数据,我们采用“滑动窗口”策略。
5.1 输入 (X) 与 目标 (Y)
假设上下文长度(Context Length)为 4:
- 输入 (X):
["The", "quick", "brown", "fox"] - 目标 (Y):
["quick", "brown", "fox", "jumps"](即将输入向右平移一位)。
5.2 PyTorch 数据管道
在 Mac Pro M4 上,我们使用 PyTorch 的 Dataset 和 DataLoader 来管理内存并加速读取:
- 批处理 (Batch Size):
- 同时训练多个样本。
- 步幅 (Stride):
- 决定窗口每次滑动的距离。如果步幅等于窗口长度,则样本间
无重叠,能有效防止过拟合。
- 决定窗口每次滑动的距离。如果步幅等于窗口长度,则样本间
6. 嵌入向量层 (Embedding Layer)
现在的token还是整数 ID,模型无法进行复杂的数学运算。我们需要将它们投影到高维空间。
6.1 token嵌入 (Token Embedding)
- 查找表:
嵌入层本质上是一个巨大的矩阵
- 维度:
- GPT-2 风格的模型通常使用 256、768 甚至 1024 维。
6.2 位置嵌入 (Positional Embedding)
- 问题:
- 注意力机制本身不具备位置感(“我吃苹果”和“苹果吃我”在它看来是一样的)。
- 解决方法:
- 为每个位置
(0, 1, 2...)也创建一个嵌入向量,并将其与token嵌入直接相加。
- 为每个位置
- GPT-2 策略:
- 使用一种简单的、可学习的位置嵌入层(不同于 Llama 3 使用的旋转位置编码 RoPE)。
🏗️ 全栈工程师实战清单 (Mac M4)
- 环境配置:由于 M4 芯片架构,建议直接通过
pip install torch安装。PyTorch 会自动支持苹果的 MPS (Metal Performance Shaders)。 - 代码练习:不要只读代码,建议打开
Jupyter Lab亲手实现SimpleTokenizer。 - 避坑指南:在 Notebook ,将
num_workers设为0可以避免多进程卡死的问题,尤其是在交互式环境下。