资料摘要:personal chatgpt 10 — 预训练语料,mapping & streaming(load_dataset)
本讲由真实视频转录与作者 notebook/代码交叉整理。原始层:🔒 带时间戳视频转录;课程总览:personal chatgpt — LLMs 实践系列。
本讲从大模型预训练语料规模切入,展示 C4、The Pile 等公开语料构成;随后转向工程问题:当数据远大于内存时,如何用 Hugging Face Datasets 的 Apache Arrow/memory mapping 和 streaming 访问数据,以及 PyTorch Dataset、IterableDataset、DataLoader 的职责差异。
课程的核心不是语料清洗算法,而是“大数据如何成为可迭代训练输入”:map-style 随机访问、流式顺序迭代、lazy map、take/skip、batching,以及有限/无限数据流。
1. 大模型预训练语料构成
Section titled “1. 大模型预训练语料构成”课件用图片列出英文与中文预训练数据来源,并重点介绍:
- C4(Colossal Clean Crawled Corpus):T5 工作中的大规模清洗网页语料;
- The Pile:由多种领域数据组成的开放语料集合,课程联系到 GPT-J-6B。
课程用多种数据源和 TB/十亿 token 级规模说明:预训练不是“下载一个文本文件”,而是需要多来源组合、清洗、存储和高吞吐迭代。精确数据配比主要存在于课件图片和原论文,本讲没有提供下载/清洗实现,因此本稿不根据 ASR 补写具体百分比。
2. Dataset 与 DataLoader 的职责
Section titled “2. Dataset 与 DataLoader 的职责”课程区分:
Dataset:定义样本从哪里来、如何取一条;DataLoader:在 Dataset 外层组织 batch、shuffle、并行 worker 等。
from torch.utils.data import DataLoader
loader = DataLoader( dataset, batch_size=8, shuffle=True, num_workers=4,)DataLoader 不是数据本身,也不能替代 Dataset 的索引/迭代逻辑。
3. Map-style Dataset
Section titled “3. Map-style Dataset”PyTorch map-style Dataset 通常实现:
class CustomDataset(torch.utils.data.Dataset): def __getitem__(self, index): ...
def __len__(self): ...特点:
- 可按 index 随机访问;
- 有明确长度;
- 适合 shuffle、采样器和有限数据集。
Hugging Face 普通 Dataset 也支持行索引、列索引、切片和格式转换。
4. Apache Arrow 与 memory mapping
Section titled “4. Apache Arrow 与 memory mapping”Hugging Face Datasets 把处理后的数据缓存成 Apache Arrow 格式。课程强调:
- Arrow 是列式内存/磁盘格式;
- memory mapping 让进程通过虚拟内存访问磁盘文件,不必一次把整个数据集复制到 Python heap;
- 操作系统按需把页面调入内存,并可共享缓存页。
课程 PubMed 实验:
dataset = load_dataset( "json", data_files=filepath, split="train",)notebook 保存输出显示:
- Arrow cache 约 19.54 GB;
- 15,518,009 行;
- 进程 RSS 约 1.57 GB;
- 历史遍历吞吐约 0.277 GB/s。
这些数字证明作者当时没有把 19.54 GB 全部常驻进程内存;它们不是当前机器重新测得的性能指标。
5. Streaming / IterableDataset
Section titled “5. Streaming / IterableDataset”iterable_dataset = load_dataset( "json", data_files=filepath, split="train", streaming=True,)特点:
- 返回/表现为可迭代数据流;
- 不要求先完整构建本地 Arrow cache;
- 可以边下载/边读取/边处理;
- 一般不能像 map-style Dataset 那样任意随机索引;
- 长度可能未知。
课程把它类比为 Python generator:每次请求下一条时才读取/处理下一条。
6. Lazy map、take 与 skip
Section titled “6. Lazy map、take 与 skip”tokenized = iterable_dataset.map( lambda x: tokenizer(x["text"]))
head = tokenized.take(10)rest = tokenized.skip(10)- 对 streaming dataset 的
map是惰性的:定义变换不会立即处理全量数据;真正迭代时才执行。 take(n)取前 n 条;skip(n)跳过前 n 条;- 两者可做流式拆分示例,但不等价于普通 Dataset 的随机切片。
7. PyTorch IterableDataset
Section titled “7. PyTorch IterableDataset”课程自定义:
class CustomIterableDataset(torch.utils.data.IterableDataset): def __iter__(self): yield ...还展示无限数据流:持续产生固定窗口大小的随机输入和标签。对无限流:
- 不能依赖自然到达数据集末尾;
- 训练必须由 step 数、时间或外部条件终止;
- 多 worker 时要考虑每个 worker 如何分片,课程 notebook 没有深入展开该规则。
8. Dataset 拼接与 DataLoader
Section titled “8. Dataset 拼接与 DataLoader”课程演示两个 map-style Dataset 的拼接和 batch 输出,说明:
- Dataset 可以组合;
- DataLoader 再按 batch 产生张量;
- 拼接后长度是各子 Dataset 长度之和;
- 对 IterableDataset 则不能假设同样的随机访问/长度语义。
公式 / 代码
Section titled “公式 / 代码”进程内存与磁盘映射数据量应分开:
Arrow 文件大小 ≠ Python 进程 RSS历史吞吐计算的概念形式:
DataLoader 批次:
Dataset/IterableDataset → DataLoader → batch → model00:00:大模型预训练语料、C4、The Pile 与 Dataset/DataLoader 概览。01:00:C4/Pile 的多来源与大规模背景。02:06:Dataset 与 DataLoader 的职责。03:31:IterableDataset、generator 和随机访问边界。05:02:Hugging Face Dataset、memory mapping 与 streaming 两种模式。05:31:Apache Arrow 列式格式。06:31:虚拟内存、磁盘映射和按需加载。08:32:约 20 GB PubMed JSONL 和load_dataset('json')。10:01:19.54 GB cache、1551 万行与约 1.57 GB RSS。11:30:历史遍历吞吐约 0.277 GB/s。12:00:streaming=True返回 iterable data stream。13:02:对 streaming dataset 惰性执行 tokenizermap。14:02:take、skip、map-style/iterable 自定义示例。
运行边界与可复现性
Section titled “运行边界与可复现性”- 预训练语料课件和小型自定义 Dataset 示例不需要 GPU。
- PubMed 路径硬编码为 Linux 绝对路径
/media/whaow/datasets/PUBMED_title_abstracts_2019_baseline.jsonl;文件未随仓库提供。 - 复现主实验需自行下载约 20 GB 数据、替换路径并准备足够磁盘空间。
- 19.54 GB、15,518,009 行、1.57 GB RSS、0.277 GB/s 均是 notebook 保存的作者环境输出,不是当前 Mac 实测。
- streaming 能降低预先下载/常驻存储要求,但仍受网络、源端可访问性、shuffle buffer、断点恢复等因素影响;课程未展开这些规则。
- DataLoader 多 worker 对 IterableDataset 的分片问题没有在本讲讲清,本稿不补写具体实现规则。
- ASR 把 C4、The Pile、Apache Arrow、memory mapping、IterableDataset、PubMed 等识别为近音词;本稿按 notebook 校正。
与前后讲关系
Section titled “与前后讲关系”- 承接第 9 讲:训练 tokenizer 和预训练模型都需要大规模语料迭代器。
- 回看第 3 讲:
Dataset.map在小数据集上用于 tokenize;本讲解释大规模场景下普通 Dataset 与 streaming map 的差异。 - 课程结构:第 1–8 讲主要处理模型、微调和数值表示;第 9–10 讲补齐文本表示和数据输入层。
- Dataset 和 DataLoader 在训练输入管线中分别负责什么?
- 为什么 19.54 GB 的 Arrow cache 可以对应约 1.57 GB 的进程 RSS?
- map-style Dataset 与 IterableDataset 在索引、长度和 shuffle 语义上有何差异?
- streaming dataset 上的
map为什么称为 lazy?take/skip与随机切片有何不同? - 当前材料为什么无法按原样复现 PubMed 吞吐实验?
- 视频:预训练语料,mapping & streaming(load_dataset)
- 转录:🔒 personal chatgpt 10 视频转录
- 课件 / 代码:🔒 pretrain_corpus_大模型预训练语料.ipynb
- 课件 / 代码:🔒 dataset_dataloader.ipynb
- 滴答清单抓取时学习状态:已完成。
- 视频正文采用自动语音识别;关键术语已用标题、notebook 与源码校正,无法确认的口语细节不扩写。
- notebook 未执行的 CUDA、权重下载、训练或外部 API 单元,不表述为已复现实验。