资讯详情

nanoGPT OpenWebText 数据预处理完整实操:800 万篇网页文档如何变成 17GB、90 亿 token 的 GPT-2 训练集

📅 2026/10/1 1:57:05 | 华诺云谱 👁 阅读
nanoGPT OpenWebText 数据预处理完整实操:800 万篇网页文档如何变成 17GB、90 亿 token 的 GPT-2 训练集
nanoGPT OpenWebText 数据预处理完整实操800 万篇网页文档如何变成 17GB、90 亿 token 的 GPT-2 训练集【免费下载链接】nanoGPTThe simplest, fastest repository for training/finetuning medium-sized GPTs.项目地址: https://gitcode.com/GitHub_Trending/na/nanoGPT800 万篇网页原文怎么变成喂给 GPT-2 的 17GB train.bin这篇文章带你走一遍 nanoGPT 里的 OpenWebText 数据预处理链路一条命令下载语料、GPT-2 BPE 分词出 90 亿 token、uint16 二进制落盘最后看训练循环如何用 memmap 零拷贝读取这批数据。语料从哪来WebText 的开源复刻版GPT-2 论文用的 WebText 数据集OpenAI 自己从未放出过原始数据nanoGPT 靠什么训练答案是 OpenWebTextOWT——社区用爬取与过滤流水线复刻出来的 WebText 开源版本合计 8,013,769 篇文档。它在 nanoGPT 里身兼两职其一从零训练的语料config/train_gpt2.py 的目标就是在 OWT 上把 124M 参数的 GPT-2 从头训到约 2.85 的验证损失其二基线评测的考卷config/eval_gpt2.py 等配置直接加载 OpenAI 官方权重在 OWT 的 val 集上报告损失。无论哪条路data/openwebtext/prepare.py 产出的 train.bin 和 val.bin 都是整条链路的地基。 一条命令生成 train.bin依赖与磁盘预算跑 prepare.py 之前你需要准备什么其实不多四个库、一条命令、一块够大的磁盘。datasetsHugging Face 的数据集库负责把 OWT 下载并缓存到本地原始缓存约占用 54GBtiktokenOpenAI 的 BPE 编码器脚本使用其中的gpt2编码numpy把 token 流以uint16类型写进二进制文件tqdm落盘阶段的进度条。装依赖并启动一共两行pip install numpy tiktoken datasets tqdm python data/openwebtext/prepare.py从仓库根目录执行脚本会把train.bin与val.bin写到脚本所在的 data/openwebtext/ 目录。耗时上全程主要受下载带宽拖累一般得放几个小时让它跑完真正要盯住的是磁盘——缓存 54GB 加上产出约 17GB建议预留 70GB 以上空间。流水线怎么转文档到二进制的四步走脚本跑起来之后里面发生了什么主线是四个阶段下载、切分、分词、落盘。下载load_dataset 拉取语料load_dataset(openwebtext)从 Hugging Face 拉取原始数据并缓存OWT 默认只含一个trainsplit。这一步的并行度由独立变量num_proc_load_dataset默认 8控制——脚本注释特意提醒加载阶段的最优进程数未必和分词阶段一致因为它还受网络带宽约束不过通常取大于 1 都比单进程好。切分切出一个极小的 val 集原始数据没有现成的验证集脚本自己切先shuffle再train_test_split取test_size0.0005、固定种子2357并把得到的test改名为val。结果 train 侧 8,009,762 篇、val 侧 4,007 篇刚好凑足 8,013,769。种子写死意味着任何人重跑都会得到同一份划分结果才谈得上可对账。分词GPT-2 BPE 与文档边界标记为什么用 GPT-2 BPE 分词因为目标是复刻官方 GPT-2分词器必须和它一致。每篇文档的编码逻辑如下def process(example): ids enc.encode_ordinary(example[text]) # 忽略特殊 token ids.append(enc.eot_token) # 50256gpt2 bpe 的文本结束符 return {ids: ids, len: len(ids)}选encode_ordinary而不是encode特殊 token 一律忽略得到纯粹的 BPE id 流每篇末尾追加eot_token50256即/text作为文档之间的边界分隔——源码注释留了个悬念叫end of text也许前置比追加更合理这是留给读者的消融点map阶段用num_proc8并行分词remove_columns[text]让原文分词完即丢省缓存空间。落盘memmap 分 1024 批顺序写入这是全脚本最讲究效率的一段。先累加出每个 split 的 token 总数用np.memmap按该长度建一个可写映射然后把数据集切成 1024 个连续分片逐片拼接写入对应区间最后 flush 强制落盘arr np.memmap(filename, dtypenp.uint16, modew, shape(arr_len,)) for batch_idx in tqdm(range(1024)): batch dset.shard(1024, indexbatch_idx, contiguousTrue).with_format(numpy) arr_batch np.concatenate(batch[ids]) arr[idx : idx len(arr_batch)] arr_batch idx len(arr_batch) arr.flush()memmap 相当于把书摊开写到哪一页就动哪一页90 亿个 token 从不需要同时装进内存按批批量拼接再写则是为了减少碎片小写、拉高写盘吞吐。uint16 为什么够存因为 GPT-2 BPE 的max_token_value是 50256小于 2 的 16 次方所有 token id 都能塞进 2 字节。这一条决定了 train.bin 停在 17GB 量级而不是 34GB。 落盘之后train.bin 格式与验证方式17GB 和 8.5MB 这两个文件里到底装着什么没有头部、没有 padding、没有任何元数据只有一条连续的uint16token 流每篇文档的 ids 首尾相接文档之间以 50256 隔开train.bin 约 17GB、共 9,035,582,198 个 tokenval.bin 约 8.5MB、4,434,897 个 token两者相差约 2000 倍与 0.0005 的切分比例严丝合缝——验证集只需要够稳地估损失而已权威规格见 data/openwebtext/readme.md。验证也简单粗暴既然文件就是裸的 uint16 序列任何语言的 mmap 都能按同样 dtype 直接映射比如用np.memmap(train.bin, dtypenp.uint16, moder)以只读方式打开立刻得到一个 90 亿元素的数组无需解析任何格式。这份无格式正是训练端穷人版数据加载器能写得那么轻的前提。⚡ 零拷贝数据加载train.py 怎么读 17GB17GB 数据不装内存train.py 的get_batch是怎么把数据送进 GPU 的核心就几行ix torch.randint(len(data) - block_size, (batch_size,)) x torch.stack([torch.from_numpy(data[i:iblock_size].astype(np.int64)) for i in ix]) y torch.stack([torch.from_numpy(data[i1:i1block_size].astype(np.int64)) for i in ix])三个设计点每次迭代都重建 memmap 对象——刻意为之规避 numpy memmap 在长训练进程中的内存泄漏注释里引用了社区的经典讨论随机起点采样在整条 token 流上随机取batch_size个起点各切一段block_size1024的窗口x是窗口内容y右移一位天然构成自回归预测对uint16 只负责存储读出来立刻转成 int64 再进模型。吞吐可以推算默认配置batch_size12、block_size1024、gradient_accumulation_steps5*8DDP 下每卡摊 58 卡合计 5 × 8 × 12 × 1024 491,520约 0.5M token/itermax_iters600000全程约 300B token正好贴着 Chinchilla 推荐的算力配比。 8 卡 DDP 启动与基线评测跑起来与避坑数据就绪后怎么启动、要注意什么启动用torchrun --standalone --nproc_per_node8 train.py config/train_gpt2.py拉起 8 卡 DDPREADME 给出的参考是 8×A100 40GB 单节点约 4 天收敛到 ~2.85 损失。基线不想训练的话跑eval_gpt2系列配置如config/eval_gpt2.py、config/eval_gpt2_medium.py加载 OpenAI 官方权重直接在 OWT 上评估gpt2124M约 3.11 train / 3.12 valgpt2-xl1558M约 2.56 / 2.54。官方 GPT-2 比 2.85 略差根源在 WebText 与开源复刻版之间的领域差距。调参与消融磁盘预算HF 缓存约 54GB 加 train.bin 17GB至少留 70GB进程数num_proc取 CPU 核数的一半左右加载与分词两个阶段的 worker 数是独立变量可分别调前者还受带宽拖累可复现性种子 2357 固定重跑必得相同划分与产出消融实验process()里 EOT 前置还是追加是官方留在代码注释里的实验位你可以自行尝试并对比损失。收尾从 8,013,769 篇文档到 90 亿个 tokenOpenWebText 预处理就是下载、切分、GPT-2 BPE 分词、uint16 落盘四步训练端再靠 memmap 随机窗口零拷贝取数全程不把数据塞进内存。下一步很简单把那条命令跑起来或者照着 data/shakespeare_char/prepare.py 换一个更小的数据集把整条链路再走一遍。【免费下载链接】nanoGPTThe simplest, fastest repository for training/finetuning medium-sized GPTs.项目地址: https://gitcode.com/GitHub_Trending/na/nanoGPT创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑