mindspore-ai / mindspore-ai/hyper-parallel
[RFC] Offline IDX/BIN 使用与转测说明
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 53
- Forks
- 63
- Avg merge
- 23h 45m
- Merged PRs (30d)
- 63
Description
Offline IDX/BIN 使用与转测说明
本文只说明 LLM Offline Indexed Dataset(.idx/.bin)的应用场景,不依赖现有训练 YAML。
内容分为两部分:
- 使用转换工具把原始文本转换为 IDX/BIN。
- 拿到已有 IDX/BIN 后,检查数据并接入训练。
不测试 VLM、图片或视频数据。转测以命令能否正常结束、数据能否读取、训练能否持续运行和 loss 是否正常等
应用侧可观测结果为准,不把内部索引或 Dataset 实现细节作为验收项。
测试人员不需要分析 position ID、attention mask 或 loss mask 等内部 Tensor;涉及这些开关的用例,只验收
训练能否正常启动和持续运行,以及 loss 是否为有限值。
统一验收标准:
- 转换或读取命令退出码为 0,日志中没有
ERROR或Traceback。 - 训练场景至少连续完成 3 个训练 step,进程无异常,loss 不为
NaN或Inf。 - 测试人员不需要检查 batch shape、记录长度或内部 Tensor 的具体数值。
一、使用转换工具生成 IDX/BIN
1. 适用场景
转换工具支持 JSON、JSONL 文件、目录或 glob 输入,并根据 --json-keys 读取文本字段。
示例 JSONL:
{"text": "first training document"}
{"text": "second training document"}
转换结果分为两类:
| 转换模式 | 使用场景 | 关键参数 | 输出记录长度 |
|---|---|---|---|
| Non-packed | 普通变长文档训练 | 不设置 --pack-to-seq-len |
可以不同 |
| Packed/pre-cut | 提前制作定长训练记录 | --pack-to-seq-len <seq_length> |
固定为 seq_length + 1 |
2. 生成 Non-packed 数据
Non-packed 模式只进行 tokenization,不在离线阶段补齐或切成定长训练记录。
python -m hyper_parallel.auto_models.components.datasets.tools.offline_preparation \
--dataset-name-or-path /path/to/train.jsonl \
--json-keys text \
--output-prefix /path/to/indexed/train \
--tokenizer-name-or-path /path/to/tokenizer \
--tokenizer-use-fast true \
--workers 8 \
--append-eod true
不要设置 --pack-to-seq-len。
输出:
/path/to/indexed/train_text_document.bin
/path/to/indexed/train_text_document.idx
3. 生成 Packed/pre-cut 数据
Packed 模式用于提前生成与模型训练长度匹配的定长记录。假设训练的 seq_length=2048:
python -m hyper_parallel.auto_models.components.datasets.tools.offline_preparation \
--dataset-name-or-path /path/to/train.jsonl \
--json-keys text \
--output-prefix /path/to/indexed/train_packed \
--tokenizer-name-or-path /path/to/tokenizer \
--tokenizer-use-fast true \
--workers 8 \
--append-eod true \
--pack-to-seq-len 2048
每条输出记录包含 2049 个 token:
2049 token
├── input_ids = text[:-1] # 2048
└── labels = text[1:] # 2048
输入结束时不足 2049 个 token 的尾部会被丢弃,不写入 PAD。
4. EOD 选项
--append-eod true 会在每个非空文档末尾追加 tokenizer 定义的 EOS/EOD token。
- 训练时必须使用相同 tokenizer,或提供完全一致的
vocab_size和eod_token_id。 - tokenizer 必须定义
eos_token_id或sep_token_id,否则追加 EOD 会失败。 - Packed 数据可以设置
--append-eod false,但记录中将没有可用于文档边界处理的 EOD。
5. 检查转换结果
先检查两个文件均存在且非空:
test -s /path/to/indexed/train_text_document.bin
test -s /path/to/indexed/train_text_document.idx
再读取元数据和少量样本:
python -m hyper_parallel.auto_models.components.datasets.tools.read_indexed_dataset \
--path /path/to/indexed/train_text_document \
--tokenizer /path/to/tokenizer \
--num-samples 3
Non-packed 数据应满足:
- sequence 和 document 数量大于 0。
- sequence 长度允许不同。
- token ID 在模型词表范围内。
- 启用
append-eod时,非空文档末尾包含正确的 EOD ID。
Packed 数据应满足:
min_length = max_length = seq_length + 1
例如 seq_length=2048 时,所有记录长度必须为 2049。
6. 转换工具限制
- 输入字段必须与
--json-keys一致,字段值应为可 tokenization 的文本。 - 输出目录必须存在或允许创建,并且具有足够的磁盘空间。
- 同一个 prefix 的
.bin/.idx必须来自同一次转换。 - 离线转换和训练必须使用相同的 tokenizer 规则。
- Packed 数据不支持 PAD;尾部不足完整记录时直接丢弃。
--pack-to-seq-len必须大于 0,并与后续训练的seq_length一致。- 数据量过小时,Packed 转换可能无法生成任何完整记录。
7. 转换工具转测场景
| 用例 | 操作 | 预期结果 |
|---|---|---|
| C-1 | JSONL 转换为 Non-packed 数据并接入训练 | 转换和读取命令正常结束,训练至少完成 3 个 step,无异常且 loss 正常 |
| C-2 | JSONL 转换为 Packed 数据并接入训练 | 转换和读取命令正常结束,训练至少完成 3 个 step,无异常且 loss 正常 |
| C-3 | 指定多个 --json-keys 进行转换 |
转换命令正常结束,各输出数据均能正常读取 |
| C-4 | 分别设置 append-eod=true/false 后接入训练 |
两种配置均至少完成 3 个训练 step,无异常且 loss 正常 |
二、拿到 IDX/BIN 后接入训练
1. 确认文件和 Dataset prefix
一个 Dataset prefix 对应两个文件:
<prefix>.bin
<prefix>.idx
配置中的 dataset.data_path 填 prefix,不带 .bin 或 .idx 后缀。
文件:
/data/train_text_document.bin
/data/train_text_document.idx
配置:
dataset.data_path: /data/train_text_document
如果不了解数据的制作方式,先使用读取工具查看长度:
python -m hyper_parallel.auto_models.components.datasets.tools.read_indexed_dataset \
--path /data/train_text_document \
--tokenizer /path/to/tokenizer \
--num-samples 3
根据检查结果选择模式:
| 已有数据特征 | is_dataset_from_mr |
要求 |
|---|---|---|
| 变长、未提前 packing 的文档 | false |
不含离线 PAD |
| 固定长度的 Packed/pre-cut 记录 | true |
每条严格为 seq_length + 1 |
2. Non-packed 数据配置示例
dataset:
model_assets:
tokenizer:
_target_: hyper_parallel.auto_models.components.datasets.llm.build_tokenizer.AutoTokenizer.from_pretrained
pretrained_model_name_or_path: /path/to/tokenizer
tokenizer_type: hf
use_fast: true
local_files_only: true
_target_: hyper_parallel.auto_models.components.datasets.llm.build_indexed_text_dataset
data_path: /data/train_text_document
data_config:
seq_length: 2048
split: "1, 0, 0"
is_dataset_from_mr: false
labels_are_shifted: true
Indexed Dataset 返回的 labels 已经是与 logits 对齐的 next-token labels,因此必须配置
labels_are_shifted: true,避免模型或 loss 再次 shift。未列出的 Dataset 参数使用默认值。转测只检查训练至少
连续完成 3 个 step,无异常且 loss 正常。
3. Packed/pre-cut 数据配置示例
dataset:
model_assets:
tokenizer:
_target_: hyper_parallel.auto_models.components.datasets.llm.build_tokenizer.AutoTokenizer.from_pretrained
pretrained_model_name_or_path: /path/to/tokenizer
tokenizer_type: hf
use_fast: true
local_files_only: true
_target_: hyper_parallel.auto_models.components.datasets.llm.build_indexed_text_dataset
data_path: /data/train_packed_text_document
data_config:
seq_length: 2048
split: "1, 0, 0"
is_dataset_from_mr: true
labels_are_shifted: true
Packed Indexed Dataset 同样已经生成 next-token labels,必须配置 labels_are_shifted: true。未列出的 Dataset
参数使用默认值。已有 Packed 数据的记录长度必须为 2049;转测只检查训练至少连续完成 3 个 step,无异常且
loss 正常。
4. 只有 token 元数据时
如果没有可加载的 Hugging Face tokenizer,但明确知道数据使用的词表和 EOD ID,可以使用
pretokenized:
dataset:
model_assets:
tokenizer:
_target_: hyper_parallel.auto_models.components.datasets.llm.build_tokenizer.AutoTokenizer.from_pretrained
pretrained_model_name_or_path: /path/to/stable/tokenizer-identity
tokenizer_type: pretokenized
vocab_size: 32000
eod_token_id: 2
vocab_size和eod_token_id必须与数据制作阶段完全一致。pretrained_model_name_or_path使用稳定、可区分该 tokenizer 的身份路径。- Pretokenized 模式不能编码或解码原始文本,只适合读取已有 token 数据。
检查命令:
python -m hyper_parallel.auto_models.components.datasets.tools.read_indexed_dataset \
--path /data/train_text_document \
--tokenizer-type pretokenized \
--vocab-size 32000 \
--eod-token-id 2 \
--num-samples 3
5. DataLoader 配置示例
两种模式都使用 Indexed 数据源:
dataloader:
_target_: hyper_parallel.auto_models.components.datasets.FixedBatchDataLoader
collate_fn:
_target_: hyper_parallel.auto_models.components.datasets.build_indexed_collate_fn
get_batch:
_target_: hyper_parallel.auto_models.components.datasets.ParallelBatch
source_type: indexed
未列出的 DataLoader 参数使用默认值。
6. EOD 训练选项
dataset:
data_config:
reset_position_ids: false
reset_attention_mask: false
eod_mask_loss: false
reset_position_ids=true:EOD 后 position ID 从 0 重新开始。reset_attention_mask=true:EOD 后的 token 不再关注前一个文档。eod_mask_loss=true:EOD 对应位置不参与 loss。- 三项均为
false:token 流按连续序列训练。
7. 已有 IDX/BIN 的使用限制
.bin/.idx必须成对存在,data_path必须填写 prefix。- 必须确认数据是 Non-packed 还是 Packed,不能只根据文件名判断。
- Packed 数据的制作
seq_length必须与训练配置一致。 - 模型
vocab_size必须大于数据中的最大 token ID。 - tokenizer 和 EOD ID 必须与数据制作阶段一致。
- tokenizer 的 PAD ID 如果存在,必须与 EOD/EOS ID 不同。
- Non-packed 数据配置
is_dataset_from_mr: false。 - Packed 数据配置
is_dataset_from_mr: true,且不允许 PAD。 - Non-packed 和 Packed Indexed 数据都必须配置
labels_are_shifted: true。 global_batch_size必须能被micro_batch_size * dp_world_size整除。- 数据量至少能够提供一个完整的全局 DP micro-batch。
8. 已有 IDX/BIN 转测场景
| 用例 | 操作 | 预期结果 |
|---|---|---|
| U-1 | 接入已有 Non-packed IDX/BIN | 至少完成 3 个训练 step,无异常且 loss 正常 |
| U-2 | 接入已有 Packed IDX/BIN | 至少完成 3 个训练 step,无异常且 loss 正常 |
| U-3 | 使用 Pretokenized 元数据接入 | 数据正常读取,至少完成 3 个训练 step,无异常且 loss 正常 |
| U-4 | 分别单独启用 reset_position_ids、reset_attention_mask、eod_mask_loss |
每种配置均至少完成 3 个训练 step,无异常且 loss 正常 |
更多数据结构说明见 Indexed Dataset 使用教程。
schema_version: 1
source: gitcode
gitcode_repo: mindspore/hyper-parallel
gitcode_issue: 348
source_url: https://gitcode.com/mindspore/hyper-parallel/issues/348
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the existing documentation entry point and the referenced index_dataset_tutorial.md, then compare them with the offline_preparation and read_indexed_dataset commands and dataset YAML examples in this issue. Done means the Non-packed, Packed, pretokenized, and EOD workflows, validation criteria, and C-1–C-4/U-1–U-4 scenarios are documented accurately.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 67/100