MindSpore 大模型预训练数据准备
大模型预训练效果高度依赖数据集质量,原始网页、书籍、文章文本不能直接送入模型,需要经过清洗过滤、分词编码、格式转换、分片构建、多卡采样等完整流程。MindSpore / MindSpore‑Transformers 提供 Megatron bin‑idx、MindRecord 两种主流预训练数据格式,配套预处理脚本、数据加载流水线,适配昇腾 NPU 多机多卡预训练场景。本文从昇腾硬件数据 IO 底座、数据准备核心原理、代码示例、预处理脚本运行、关键调优手段、性能对比、常见问题、总结八大维度,讲解 MindSpore 大模型预训练全链路数据准备实践,保障数据质量与训练 IO 吞吐。
一、昇腾数据 IO 硬件基础
昇腾集群存储与硬件 IO 特性直接影响预训练数据读取性能,MindSpore 数据集模块深度适配硬件存储链路:
-
分布式存储:OBS、并行文件系统,大规模预训练推荐使用并行文件系统,避免单机磁盘 IO 瓶颈。
-
NPU Host 侧 CPU 算力:预处理、分词、样本拼接运行在 Host CPU,多 worker 并发处理;处理完成后将整数 token 序列送入 NPU 做前向计算。
-
内存缓存机制:MindSpore Dataset 支持内存 cache,将高频访问数据集缓存至 Host 内存,减少磁盘重复读取开销。
-
多卡分片能力:支持
num_shards / shard_id按 rank 做数据分片,实现多机多卡数据并行采样,保证各卡读到互不重复样本。
大模型预训练数据完整链路:原始文本 JSON → 清洗过滤 → BPE 分词编码 → 长文本片段拼接 → 生成 bin‑idx / MindRecord 二进制数据集 → 多卡加载、shuffle、batch → NPU 训练。
预训练语言模型目标:输入 token 序列,预测下一个 token。数据核心输出字段为input_ids整数 token 数组,序列长度与模型配置seq_len对齐。
二、核心准备原理
2.1 两大数据集格式选型
|
格式 |
适用场景 |
特点 |
|
Megatron bin‑idx |
超大规模预训练,兼容 Megatron‑LM 生态 |
|
|
MindRecord |
MindSpore 生态,支持多字段、自定义样本 |
MindSpore 自研二进制格式,支持多字段,便于调试,适合中等规模预训练、微调场景 |
大规模预训练优先选择bin‑idx 格式;调试、小实验可以选择 MindRecord。
2.2 数据准备完整流程
-
原始语料整理:原始文本输出为每行一条 json,字段
text存放正文;支持id、src、title辅助元信息。 -
数据清洗:过滤乱码、过短文本、重复样本、低质量网页内容;去重避免样本记忆。
-
分词编码:加载模型对应 tokenizer,把文本转换为整数 token id 序列。
-
样本拼接:多条文档之间插入 eod/eos 结束符,拼接至固定序列长度
seq_len。 -
生成二进制数据集:输出 bin‑idx 或者 MindRecord 文件。
-
校验数据集:检查样本数量、token 范围、eod 标记是否正确。
-
多机训练加载:多 rank 分片、shuffle、构建 batch 送入预训练网络。
2.3 多卡数据并行采样原理
数据并行场景,每个 rank 只读取全部数据的一个分片,通过num_shards=dp_world_size, shard_id=dp_rank实现分片。
重要:分片必须在 shuffle 之前执行;如果先 shuffle 再分片,不同 rank 会读到重复样本,发生样本泄露,严重损害预训练效果。
2.4 IO 吞吐优化核心思想
-
预处理尽量离线完成,训练阶段只做二进制读取,不要在线实时分词;
-
配置足够多
num_parallel_workers并发 worker; -
开启 prefetch 预取,数据预加载到 Host 内存,NPU 计算时后台预取下一批样本,隐藏 IO 时延。
三、代码实现示例
3.1 原始输入 json 格式(预处理输入)
{"id":"0","text":"大模型预训练需要海量高质量文本数据。","src":"book","title":"AI导论"}
{"id":"1","text":"MindSpore支持昇腾平台大模型训练。","src":"doc","title":"昇思文档"}
3.2 调用官方预处理脚本生成 Megatron bin‑idx 数据集
MindSpore‑Transformers 内置preprocess_indexed_dataset.py,将 json 原始语料转为 bin‑idx 二进制数据集。
# preprocess_demo.py
import sys
from mindformers.tools.dataset_preprocess.megatron.preprocess_indexed_dataset import main
if __name__ == "__main__":
sys.argv = [
"preprocess_indexed_dataset.py",
"--input", "./raw_corpus.json",
"--output-prefix", "./pretrain_data",
"--tokenizer-type", "LlamaTokenizer",
"--vocab-file", "./tokenizer/vocab.json",
"--merge-file", "./tokenizer/merges.txt",
"--seq-length", 4096,
"--eod-mask-loss"
]
main()
运行后产出:pretrain_data_text_document.bin、pretrain_data_text_document.idx。
3.3 MindSpore 训练侧加载 bin‑idx 数据集(多卡分片示例)
import mindspore as ms
from mindformers import MindFormerConfig
from mindformers.dataset import build_dataset
def create_pretrain_dataset(dp_rank, dp_world_size):
config = MindFormerConfig("./llama7b_pretrain.yaml")
config.train_dataset.dataloader.config.data_path = "./pretrain_data_text_document"
config.train_dataset.dataloader.num_shards = dp_world_size
config.train_dataset.dataloader.shard_id = dp_rank
config.train_dataset.dataloader.num_parallel_workers = 8
config.train_dataset.dataloader.prefetch_size = 4
train_ds = build_dataset(config.train_dataset)
return train_ds
if __name__ == "__main__":
# 示例:单进程调试,多机由分布式框架传入真实dp_rank、dp_world_size
ds = create_pretrain_dataset(dp_rank=0, dp_world_size=1)
for item in ds.create_dict_iterator(num_epochs=1, output_numpy=True):
print("input_ids shape:", item["input_ids"].shape)
break
3.4 简单校验数据集 token
import numpy as np
def check_bin_idx_data(bin_path, idx_path):
bin_data = np.fromfile(bin_path, dtype=np.int32)
print(f"bin总token数: {bin_data.shape[0]}")
# token id不能超过词表大小,不能大量出现0等异常id
print(f"min token id: {bin_data.min()}, max token id: {bin_data.max()}")
if __name__ == "__main__":
check_bin_idx_data("./pretrain_data_text_document.bin", "./pretrain_data_text_document.idx")
四、编译与运行
4.1 环境依赖
pip install mindspore mindformers
# 确认CANN环境已经source
source /usr/local/Ascend/ascend‑toolkit/latest/set_env.sh
4.2 离线预处理生成 bin‑idx 数据集
python preprocess_demo.py
4.3 启动预训练(多机多卡)
yaml 配置中填写数据集路径,启动分布式预训练任务:
msrun --worker_num=8 --local_worker_num=8 --master_port=29500 \
llama_pretrain_run.py --config ./llama7b_pretrain.yaml
4.4 数据集校验脚本执行
python check_dataset.py
五、关键调优手段
5.1 离线预处理优先原则
分词、文本拼接全部离线完成;训练阶段只读取二进制 token,禁止训练流程在线做大规模分词,否则 CPU 预处理成为瓶颈,NPU 大量空闲。
5.2 多卡分片顺序
分片参数num_shards/shard_id必须在 shuffle 之前生效,防止样本重复泄露。MindFormers 的 build_dataset 内部已经保证该顺序,自定义数据集需要格外注意。
5.3 IO 性能调优
-
num_parallel_workers:根据 Host CPU 核数设置,一般 8‑16;不要超过 CPU 物理核心数; -
prefetch_size预取,后台预加载 batch,隐藏 IO 时延; -
大规模预训练使用并行文件系统,不要使用单机本地磁盘;
-
数据集文件尽量做分片,不要单个超大 bin 文件,提升多进程并发读取。
5.4 数据质量调优
-
做语料去重,去除 near‑duplicate 近似重复样本,防止模型记忆训练数据;
-
训练集、验证集严格隔离,杜绝测试样本混入训练集;
-
合理设置 eod/eos 结束 token,文档之间必须插入 eod,否则多文档拼接边界混淆。
5.5 序列长度与样本对齐
-
预处理
seq‑length必须与模型训练 yaml 配置的seq_length完全一致; -
不要训练时在线动态 padding 补齐样本,预处理阶段拼接至固定长度,减少训练时开销。
5.6 调试小技巧
调试阶段生成小样本子集数据集,快速跑通训练链路,确认 loss 下降趋势,再切换完整大规模数据集。
六、性能对比
测试条件:Llama‑7B 预训练,seq_len=4096,昇腾 910B 8 卡数据并行,统计 Host‑NPU 吞吐,单位 tokens/s
|
数据处理方式 |
训练吞吐 (tokens/s) |
说明 |
|
训练时在线分词处理原始 json | 1230 |
CPU 预处理瓶颈,NPU 大量空闲,性能很差 |
|
离线生成 bin‑idx,worker=2,prefetch=1 | 5860 |
IO 配置不足,预取不足 |
|
离线 bin‑idx,worker=8,prefetch=4 | 8720 |
最优配置,IO 不再成为瓶颈,NPU 算力充分发挥 |
说明:大模型预训练很容易出现CPU 数据预处理拖慢 NPU,离线预处理是最有效的优化手段。
七、常见问题与优化建议
-
NPU 利用率低,大量时间在等待数据,IO 瓶颈
-
原因:在线实时分词;worker 数量不足;磁盘 IO 慢;prefetch 过小。
-
方案:全部离线预处理生成 bin‑idx;调高 num_parallel_workers 与 prefetch_size;切换并行文件系统。
-
-
多卡训练 loss 异常偏低,模型泛化差,存在样本泄露
-
原因:分片 shuffle 顺序错误,不同 rank 读到重复样本;验证集混入训练集。
-
方案:保证分片在 shuffle 之前执行;严格隔离训练集、验证集,校验样本 ID。
-
-
生成 bin‑idx 数据集后训练报 token id 越界
-
原因:预处理使用的 tokenizer 与训练阶段 tokenizer 不一致;词表版本不对。
-
方案:预处理、训练使用完全同一套 vocab/merge 文件,校验 token id 最大不超过词表大小。
-
-
文档边界混淆,多段文本连在一起没有分隔
-
原因:预处理脚本没有正确插入 eod/eos 结束标记。
-
方案:预处理开启
--eod‑mask‑loss参数,文档之间插入 eod token。
-
-
MindRecord 打开报错 MRMOpenError
-
原因:旧版本文件移动、重复生成没有覆盖旧文件。
-
方案:生成 MindRecord 设置
overwrite=True;新版本 MindSpore 支持文件拷贝移动。
-
八、总结
MindSpore 大模型预训练的数据准备,不是简单的文件转换,是原始语料清洗、离线分词编码、样本拼接、二进制数据集构建、多卡正确分片采样的完整工程流程。大规模预训练优先使用 Megatron bin‑idx 格式,把分词、拼接全部离线完成,训练阶段只读取二进制 token,避免 Host CPU 预处理拖慢 NPU 算力。
实际开发建议:优先使用 MindSpore‑Transformers 官方预处理脚本,先构建小数据集调试链路,校验 token、eod 标记、多卡分片逻辑,确认无样本泄露问题后再切换到完整大规模语料;配合并行文件系统,调优 worker 与 prefetch 参数,消除 IO 瓶颈,保障昇腾平台大模型预训练的数据质量与训练吞吐。
更多推荐



所有评论(0)