ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

nanoGPT OpenWebText 数据集预处理实战:从 8 万篇文档到 9B token 的 train.bin/val.bin

nanoGPT OpenWebText 数据集预处理实战:从 8 万篇文档到 9B token 的 train.bin/val.bin 人工智能大模型预训练深度学习微调【免费下载链接】nanoGPTThe simplest, fastest repository for training/finetuning medium-sized GPTs.项目地址https://gitcode.com/GitHub_Trending/na/nanoGPT点击查看免费下载导读OpenWebTextOWT是 OpenAI 私有 WebText 数据集的公开复刻版本是 nanoGPT 复现 GPT-2 的关键训练语料。本文以 data/openwebtext/readme.md 为骨架结合 data/openwebtext/prepare.py 与 train.py 源码完整拆解 OpenWebText 的下载、切分、GPT-2 BPE 分词与二进制落盘全流程。读完本文你将掌握为什么训练/验证集会产出 17GB 与 8.5MB 的 .bin 文件、9,035,582,198 个训练 token 是如何产生的、.bin 文件的底层格式约定以及 nanoGPT 训练循环如何通过np.memmap零拷贝读取这批数据。一、OpenWebText 在 nanoGPT 中的定位OpenWebText 是 OpenAI 在 GPT-2 论文 中讨论的 WebText 数据集的开源复刻原始网页快照来自 Reddit 外链过滤后的网页集合。由于 OpenAI 从未公开 WebText 本身社区用爬虫与过滤流水线尽力复刻出 OpenWebTextCorpus约 800 万篇文档托管于 Hugging Facedatasets生态的openwebtext数据集。在 nanoGPT 中OpenWebText 承担两个角色从零训练from scratch默认配置 config/train_gpt2.py 的目标就是在 OWT 上把 GPT-2 (124M) 从头训练到约 2.85 的验证损失基线评测baseline evalconfig/eval_gpt2.py 等一系列配置直接加载 OpenAI 官方 GPT-2 权重在 OWT 的 val 集上报告损失。因此prepare.py产出的train.bin/val.bin是整个复现链路的数据地基。该脚本参考了 HazyResearch flash-attention 训练管线中language_modeling_hf.py的数据处理思路见 data/openwebtext/prepare.py 注释。二、运行环境与依赖运行prepare.py需要以下依赖与项目根目录 README.md 中列出的依赖一致pip install numpy tiktoken datasets tqdm其中datasetsHugging Face 数据集库负责下载并缓存 OpenWebText约 8,013,769 篇文档缓存占用约 54GB见脚本注释tiktokenOpenAI 的快速 BPE 编码器prepare.py使用其gpt2编码numpy用于把 token 序列以uint16类型写入 memmap 二进制文件tqdm落盘阶段的分批进度条。执行入口极其简单python data/openwebtext/prepare.py在仓库根目录运行后会在data/openwebtext/目录下生成train.bin与val.bin脚本通过os.path.join(os.path.dirname(__file__), f{split}.bin)将文件写到脚本所在目录见 data/openwebtext/prepare.py。三、预处理全流程源码级拆解prepare.py的主流程在if __name__ __main__:块内共四个阶段下载加载 → 划分数据集 → 分词 → 二进制落盘。下面逐阶段展开。3.1 下载与加载load_datasetdataset load_dataset(openwebtext, num_procnum_proc_load_dataset)脚本通过 Hugging Facedatasets的load_dataset(openwebtext)拉取并缓存原始语料默认只包含trainsplitnum_proc_load_dataset默认等于num_proc 8控制加载阶段的多进程数。脚本注释特别提醒加载阶段的较优进程数可能与分词阶段不同因为它还受网络带宽影响但通常大于 1 比等于 1 更好。3.2 切分train_test_splitsplit_dataset dataset[train].train_test_split(test_size0.0005, seed2357, shuffleTrue) split_dataset[val] split_dataset.pop(test) # rename the test split to val由于 OWT 原始数据只有 train 一个 split脚本用train_test_split自行切出验证集test_size0.0005、固定随机种子2357、并先shuffleTrue再切分保证可复现随后把test改名为val。切分结果脚本中保留的注释为DatasetDict({ train: Dataset({ features: [text], num_rows: 8009762 }) val: Dataset({ features: [text], num_rows: 4007 }) })这正好对应 readme 中来自 8,013,769 篇文档的总量8,009,762 4,007。3.3 分词GPT-2 BPE 编码enc tiktoken.get_encoding(gpt2) def process(example): ids enc.encode_ordinary(example[text]) # encode_ordinary ignores any special tokens ids.append(enc.eot_token) # add the end of text token, e.g. 50256 for gpt2 bpe out {ids: ids, len: len(ids)} return out tokenized split_dataset.map( process, remove_columns[text], desctokenizing the splits, num_procnum_proc, )几个值得注意的细节encode_ordinary而非encodeencode_ordinary忽略所有特殊 token文档中的原始文本被纯 BPE 编码为 id 序列追加 EOT token每篇文档编码后追加enc.eot_tokenGPT-2 BPE 中为 50256即|endoftext|作为文档边界分隔符。脚本注释还留下了一个耐人寻味的讨论EOT 或许应该前置而非追加因为名字叫 eotend of text——这也是 nanoGPT 作者留给读者的一个可实验点map阶段并行num_proc8并行分词remove_columns[text]在分词后立即丢弃原文只保留ids与len节省缓存。3.4 二进制落盘np.memmap 顺序写入for split, dset in tokenized.items(): arr_len np.sum(dset[len], dtypenp.uint64) filename os.path.join(os.path.dirname(__file__), f{split}.bin) dtype np.uint16 # (can do since enc.max_token_value 50256 is 2**16) arr np.memmap(filename, dtypedtype, modew, shape(arr_len,)) total_batches 1024 idx 0 for batch_idx in tqdm(range(total_batches), descfwriting {filename}): batch dset.shard(num_shardstotal_batches, 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()这是全脚本最讲究效率的一段dtype np.uint16的依据GPT-2 BPE 的max_token_value 50256 2**16即所有 token id 都落在uint16范围内因此可以用 2 字节存储一个 token这是train.bin体量约 9B × 2 字节 ≈ 18GB 量级的决定性因素memmap 免内存拷贝np.memmap以w模式创建文件并直接映射避免一次性把 9B 个 token 全部装入 RAM1024 批分片写入用dset.shard(num_shardstotal_batches, indexbatch_idx, contiguousTrue)把数据集切成 1024 个连续分片逐批np.concatenate后写进 memmap 对应区间最后arr.flush()确保落盘。脚本注释说明这是Batch together samples for faster write即通过批量拼接减少小写入次数、提高写盘吞吐。四、产出文件的规格readme 核心数据运行完成后data/openwebtext/readme.md 给出了权威的产出规格文件大小token 数train.bin~17GB9,035,582,198约 90 亿val.bin~8.5MB4,434,897约 440 万数据源总计8,013,769 篇文档train 8,009,762 val 4,007两个文件内部都是单条连续的 token id 流每篇文档的 ids 首尾相接文档间以 EOT token 50256 分隔以uint16原始字节存储没有头部、没有 padding、没有任何元数据训练集与验证集规模相差约 2000 倍这与test_size0.0005的切分比例一致符合验证只需足够估计损失、训练需要海量数据的常规做法。五、如何验证与读取 .bin 文件readme 与脚本末尾都给出了用 numpy 反向读取的验证方式# m np.memmap(train.bin, dtypenp.uint16, moder)由于文件只是裸的 uint16 序列任何语言都可以用memmap/mmap按同样的 dtype 直接映射读取无需解析格式。这是 nanoGPT 数据管线poor mans data loader能够高效工作的前提。六、下游消费train.py 如何吃进 17GB 的 train.binnanoGPT 的 train.py 用穷人版数据加载器get_batch直接消费这批文件train.pydata_dir os.path.join(data, dataset) # dataset openwebtext def get_batch(split): if split train: data np.memmap(os.path.join(data_dir, train.bin), dtypenp.uint16, moder) else: data np.memmap(os.path.join(data_dir, val.bin), dtypenp.uint16, moder) 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]) ...三个要点每次迭代都重新np.memmap这是刻意为之目的是避免 numpy memmap 对象在长训练进程中的内存泄漏脚本注释引用了 Stack Overflow 上关于 memmap 内存占用的经典讨论随机位置采样torch.randint(len(data) - block_size, (batch_size,))在整条 token 流上随机取batch_size个起点每个起点切出block_size1024的连续窗口x是窗口内 tokeny是右移一位的目标 tokendata[i1 : i1block_size]构成自回归预测对uint16 → int64 转换memmap 读出后经.astype(np.int64)再进模型uint16只承担存储压缩角色。这种设计意味着不必把 17GB 数据读进内存训练循环只需按需映射并取窗口这正是 nanoGPT 能在单节点单机乃至 8×A100上高效训练的关键之一。默认配置下每轮迭代的 token 吞吐为gradient_accumulation_steps * ddp_world_size * batch_size * block_sizetrain.py在 config/train_gpt2.py 中为12 × 1024 × 5 × 8 491,520 ≈ 0.5Mtoken/itermax_iters600000总计约 300B token。七、从数据到模型复现 GPT-2 的启动方式数据就绪后即可按 README.md 的指引启动训练torchrun --standalone --nproc_per_node8 train.py config/train_gpt2.pytorchrun --standalone --nproc_per_node8单节点 8 卡 PyTorch Distributed Data ParallelDDP启动方式config/train_gpt2.py 的配置要点batch_size12、block_size1024、gradient_accumulation_steps5*8配合 8 卡使总 batch ≈ 0.5M tokenmax_iterslr_decay_iters600000按 Chinchilla 规律对应 300B tokeneval_interval1000、eval_iters200、log_interval10、weight_decay1e-1README 说明该训练在 8×A100 40GB 节点上约 4 天收敛到 ~2.85 损失而 OpenAI 官方 GPT-2 直接在 OWT 上评估约 3.11存在 WebText 与 OpenWebText 的领域差异微调后可对齐到 ~2.85 区间。若只想对已产出的 val 集做基线评测可以运行python train.py config/eval_gpt2.py python train.py config/eval_gpt2_medium.py python train.py config/eval_gpt2_large.py python train.py config/eval_gpt2_xl.py这些配置文件如 config/eval_gpt2.py通过eval_onlyTrue、init_fromgpt2/gpt2-medium/gpt2-large/gpt2-xl加载 OpenAI 权重并在 OWT 上评估得到 README 基线表格中的 train/val lossgpt2 124M 约 3.11/3.12gpt2-xl 1558M 约 2.56/2.54。八、实践注意事项磁盘与缓存预算Hugging Face 缓存目录需要约 54GB脚本注释产出train.bin~17GB、val.bin~8.5MB请预留足够空间.bin文件在脚本同目录data/openwebtext/下生成进程数调优num_proc8是脚本默认值注释建议取CPU 核心数的一半左右num_proc_load_dataset与分词进程数可分开调优前者受网络带宽影响采样随机性train_test_split使用固定种子2357任何人运行该脚本都会得到相同的 train/val 划分与相同的 .bin 产出这是复现结果可对账的前提EOT 位置的可实验性脚本注释明确提示 EOT或许应该前置而不是追加如果你做消融实验可以直接修改process()中的ids.append(enc.eot_token)行为后重新生成 .bin训练端无需改动只要train.py中的datasetopenwebtext指向正确目录训练循环会自动映射train.bin/val.bin无需任何额外配置。九、小结从 8,013,769 篇原始文档到 17GB 的train.bin9,035,582,198 token与 8.5MB 的val.bin4,434,897 tokenOpenWebText 预处理管线通过tiktokenGPT-2 BPE 编码、np.uint16压缩存储与 memmap 顺序写入在合理的内存预算内完成了语料的token 化 二进制化。下游train.py的get_batch再以 memmap 随机窗口方式零拷贝取数形成了一条从语料到 GPU 训练的高效数据链路。理解这条链路是你在 nanoGPT 上复现 GPT-2、更换数据集或调整采样策略的第一步。赞分享人工智能大模型预训练深度学习微调【免费下载链接】nanoGPTThe simplest, fastest repository for training/finetuning medium-sized GPTs.项目地址https://gitcode.com/GitHub_Trending/na/nanoGPT点击查看免费下载相关推荐nanoGPT训练实战从莎士比亚到OpenWebTextnanoGPT训练实战从莎士比亚到OpenWebText 本文详细介绍了nanoGPT项目在字符级语言模型训练和OpenWebText数据集预处理方面的完整流人工智能大模型预训练深度学习微调NanoGPT 数据准备完全指南字符级 Shakespeare 与 BPE OpenWebText 的二进制 Token 流水线NanoGPT 数据准备完全指南字符级 Shakespeare 与 BPE OpenWebText 的二进制 Token 流水线 nanoGPT 是 AndrAI 技能人工智能大模型深度学习scikit-learn 手写数字数据集digits完全指南从 NIST 预处理到 8×8 像素的 10 类分类实战scikit learn 手写数字数据集digits完全指南从 NIST 预处理到 8×8 像素的 10 类分类实战 导读 digits 数据集是 sc人工智能机器学习数据科学上一篇终极暗黑2存档编辑器网页版快速打造完美角色的完整指南下一篇终极指南使用DDrawCompat让经典DirectX游戏在现代Windows上完美运行创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表