
XTuner 使用 FTDP Processed 数据集训练 InternLM2从离线 Token 化到 Turbomind 评测全流程指南【免费下载链接】xtunerA Next-Generation Training Engine Built for Ultra-Large MoE Models项目地址: https://gitcode.com/GitHub_Trending/xt/xtuner本文面向已经使用闭源数据处理工具 FTDP 完成数据预处理、并希望用 XTuner 训练 InternLM2 系列模型的用户完整讲解Processed预处理数据集 InternLM2这一标准落地场景。你将掌握如何将统一格式的 ftdp processed 数据离线 token 化为可直接训练的.bin格式、如何基于 XTuner 内置模板导出并修改训练 config、如何固化数据读取顺序以保证跨集群训练可复现以及如何分别在 Slurm 集群和阿里云 DLC 中启动训练并完成模型格式转换与评测。文中所有命令与配置均可在当前仓库中直接运行或对应到具体源码实现。⚠️ 适用范围提示FTDP 是一款闭源数据处理工具非 FTDP 用户可跳过本文。本文对应场景为使用尚未 token 化的 ftdp 数据训练 InternLM2 模型即 internevo_migration/ftdp_dataset 中描述的 Case 1数据未 tokenized、使用 InternLM2 对话模板、训练 InternLM2。其他场景非 InternLM2 模型、普通对话数据、已 tokenized 数据请参考同目录下的其他文档。一、整体思路从 processed 到可直接训练的 tokenized 数据FTDP 把 SFT 任务的数据处理划分为三个类型原始数据origin、预处理数据processed和 token 过的数据tokenized。其中processed 数据是经过 FTDP 统一格式化的中间产物其 message 结构形如dict(role..., content..., name..., type...)还不能直接送入训练器需要先将其 token 化得到直接可以用于训练的格式。整个流程可以概括为五步离线 token 化 → 导出模板 config → 修改 config → 启动训练 → 转换并评测模型。下面从第一步开始逐步展开。二、步骤 1离线 Token 化 processed 数据集2.1 数据目录结构要求预处理数据需要满足以下目录结构processed-dir是统一入口|-- processed-dir |-- data1 | |-- processed | |-- sft_chat | |-- data1.jsonl |-- data2 | |-- processed | |-- sft_chat | |-- data2.jsonl从源码看tokenize_ftdp_datasets.py 会递归扫描processed-dir只处理路径中包含/processed/且以.jsonl结尾的文件并以processed的上一级目录名即data1、data2作为数据集名。因此目录结构必须符合上述约定否则文件会被跳过。2.2 执行离线 token 化$ python xtuner/tools/tokenize_ftdp_datasets.py \ --processed-dir /path/to/preprocessed/data \ --tokenized-dir /path/to/tokenized/data \ --tokenizer-path pretrained_model_name_or_path三个核心参数的说明如下参数含义说明--processed-dir预处理数据路径必须是具有 ftdp 标准格式的预处理数据路径即上述目录结构中的processed-dir--tokenized-dirtoken 化结果存储路径指定 token 化后的数据保存位置--tokenizer-pathtokenizer 路径取值同 HuggingFacefrom_pretrained接口的pretrained_model_name_or_path例如internlm/internlm2-7b也支持本地路径命令执行成功后会在/path/to/tokenized/data/chatml_llamav13_32k路径下保存两个子文件夹——train和valid。后续训练时使用的数据路径即为其中的train子目录。2.3 源码剖析token 化到底做了什么结合 tokenize_ftdp_datasets.py 的实现这一步实际完成了三件关键工作1为 tokenizer 补充特殊 token。脚本内置了SEPCIAL_TOKENS列表|plugin|、|interpreter|、|action_end|、|action_start|、|im_end|、|im_start|这些是 InternLM2 对话模板中用于表达智能体agent、工具tool调用能力的标记。tokenizer_add_special_tokensL389-L394会逐个检查这些 token 是否已在词表中若不存在则通过tokenizer.add_tokens(special_tokensTrue)追加。InternLM2 原生词表已包含这些 token因此本场景通常不会改变词表大小。2按 chatml 模板拼接并编码每轮对话。核心函数chatml_format使用CHATML_LLAMAV13_32K_TOKEN_CFG中定义的role_cfgL18-L92对system / user / assistant / environment / tool / thought各角色进行格式化user以|im_start|user\n开头、|im_end|\n结尾assistant同理包裹且其loss配置为iclTrue, currentTrue, endTrue表示 assistant 输出部分参与 loss 计算tool角色则以|action_start|与|action_end|包裹并归属 assistant。max_len配置为32 * 102432ktoken 序列会被截断到该长度。值得注意的实现细节是需要计算 loss 的 token 保持正数不需要计算 loss 的 token如 user 输入、系统提示等被编码为负数loss配置通过begin/end/current等标志位控制。3写入.bin与.bin.meta文件。write_bin_meta_binL271-L317会把每个样本按{tokens: token_ids}的 JSON 行写入train/数据集名/文件名.bin并额外写入每 100 个样本抽取 1 个到valid目录下。同时用np.save保存.bin.meta文件记录每个样本在.bin中的字节偏移量与 token 长度——这是训练阶段实现随机读取的基础。若valid样本数不足 500脚本会删除对应的 valid 文件源码注释说明这是经验值需大于 DP 并行数。脚本结束时还会打印all train tokens / all train samples / all valid tokens / all valid samples等统计信息可用于核对数据规模。三、步骤 2导出模板 config 文件XTuner 在仓库中内置了训练 InternLM2 的 tokenized 数据集模板位于 xtuner/configs/internlm/internlm2_7b/internlm2_7b_w_tokenized_dataset.py。使用以下命令将其导出到当前目录$ xtuner copy-cfg internlm2_7b_w_tokenized_dataset .执行成功后当前目录下会出现一个名为internlm2_7b_w_tokenized_dataset_copy.py的新文件后续所有修改都针对这个副本进行不要直接改动仓库内的模板文件。四、步骤 3修改模板 config 文件4.1 修改训练数据路径将模板中的训练数据路径替换为步骤 1 生成的真实数据路径。注意这里/path/to/tokenized/data与步骤 1 中的--tokenized-dir必须是同一个路径并进一步定位到chatml_llamav13_32k/train####################################################################### # PART 1 Settings # ####################################################################### # Model pretrained_model_name_or_path internlm/internlm2-7b use_varlen_attn True # Data - dataset_folder /path/to/sft/data/folder dataset_folder /path/to/tokenized/data/chatml_llamav13_32k/train prompt_template PROMPT_TEMPLATE.internlm2_chat max_length 32768 pack_to_max_length True ...模板中几个关键配置项的含义如下对应 internlm2_7b_w_tokenized_dataset.pyuse_varlen_attn True启用变长注意力可对 packed 后长度不等的序列做注意力掩码显著降低 padding 带来的显存浪费开启后建议batch_size 1模板注释说明增大 batch size 等价于增大max_length。prompt_template PROMPT_TEMPLATE.internlm2_chat指定 InternLM2 对话模板与步骤 1 中 token 化时使用的 chatml 格式保持一致。max_length 32768与 token 化阶段的 32k 截断长度对齐。pack_to_max_length True将多个样本拼接packing到max_length保证显存利用率。训练数据读取链路的底层实现在 xtuner/dataset/intern_repo.pyload_intern_repo_tokenized_datasetL235-L265通过os.walk收集dataset_folder下所有.bin文件交给JsonlDatasetL22-L126读取。JsonlDataset会把 token 化阶段写入的负数 token 还原为input_ids取绝对值并把负数位置对应的labels置为-100——这与chatml_format的负 token 表示不计算 loss设计一一对应-100是交叉熵损失的标准忽略值。随后build_packed_dataset借助.bin.meta中的偏移量实现样本级随机访问由PackedDatasetL128-L232按packed_length将多个样本拼接为一个训练样本。在分布式训练中该数据集只在 rank 0 上构建再通过broadcast_object_list广播给其他 rankL352-L362避免多进程重复构建造成 NFS 过载。4.2 可选DeepSpeed 训练时只保存模型权重在使用 DeepSpeed 训练时如果希望保存 checkpoint 时只保存模型权重而不保存优化器状态可大幅节省磁盘空间例如不需要断点续训的场景可按如下两步修改确保 mmengine 版本不低于 0.10.3$ pip install mmengine0.10.3在 Config 的default_hooks中给CheckpointHook增加save_optimizerFalsedefault_hooks dict( # record the time of every iteration. timerdict(typeIterTimerHook), # print log every 100 iterations. loggerdict(typeLoggerHook, interval1), # enable the parameter scheduler. param_schedulerdict(typeParamSchedulerHook), # save checkpoint per epoch. checkpointdict( typeCheckpointHook, save_optimizerFalse, by_epochFalse, intervalsave_steps, max_keep_ckptssave_total_limit), # set sampler seed in distributed evrionment. sampler_seeddict(typeDistSamplerSeedHook), )⚠️重要限制设置save_optimizerFalse后checkpoint 中不再包含优化器状态训练过程不可 resume。请仅在确认不需要断点续训时开启。五、步骤 4获取数据顺序可选但推荐5.1 为什么需要固化数据顺序训练数据的提供顺序可能会对模型的最终训练成果产生影响。由于不同集群中通过os.walk遍历目录得到的结果可能存在差异为保证训练结果的稳定性和可控性官方建议先确立所有训练数据文件的相对次序在后续训练中用它替代os.walk的默认遍历顺序。5.2 生成数据顺序文件运行以下命令获取数据顺序并保存为 txt 文件$ python xtuner/tools/get_data_order.py \ --data-folder /path/to/tokenized/data \ --save-folder /folder/to/save/data/order \ --file-type ${file_type}其中--file-type ${file_type}表示统计所有以${file_type}为文件名后缀的文件顺序。例如获取/path/to/tokenized/data路径下所有以.bin结尾的文件的顺序并保存到当前目录$ python xtuner/tools/get_data_order.py \ --data-folder /path/to/tokenized/data \ --save-folder . \ --file-type .bin从源码看get_data_order.py 内部同样使用os.walkfollowlinksTrue遍历但对目录和文件都做了sorted()排序且保存的是相对路径fp.replace(data_folder, )[1:]这样即使在不同集群、不同挂载点上也能得到完全一致的数据顺序。最终生成的顺序文件固定命名为data_order.txt。5.3 在 config 中启用数据顺序获得数据顺序文件后在 Config 的PART 3 Dataset Dataloader部分设置data_order_path... ####################################################################### # PART 3 Dataset Dataloader # ####################################################################### train_dataset dict( typebuild_packed_dataset, dataset_cfgdict( typeload_intern_repo_tokenized_dataset, - data_order_pathNone, data_order_path/folder/to/save/data/order/data_order.txt, folderdataset_folder, min_length0, file_type.bin ), packed_lengthmax_length, seed1024)对应的实现位于 intern_repo.py当data_order_path不为None时load_intern_repo_tokenized_dataset会通过 HuggingFaceload_dataset(text, data_files...)读取data_order.txt并把每行相对路径拼接上folder作为完整路径从而完全绕开os.walk否则才走默认的os.walk遍历逻辑。seed1024控制PackedDataset内的随机打乱保证多卡/多次实验的 packing 结果一致。六、步骤 5启动训练6.1 在 Slurm 集群中启动$ srun ${SRUN_ARGS} xtuner train internlm2_7b_w_tokenized_dataset_copy.py --launcher slurm --deepspeed deepspeed_zero1若训练过程中出现 OOM显存不足可尝试显存占用更小的 ZeRO 优化策略。例如使用 zero 3$ srun ${SRUN_ARGS} xtuner train internlm2_7b_w_tokenized_dataset_copy.py --launcher slurm --deepspeed deepspeed_zero3--deepspeed参数对应仓库 xtuner/configs/deepspeed 下的 DeepSpeed 配置deepspeed_zero1.json、deepspeed_zero2.json、deepspeed_zero2_offload.json、deepspeed_zero3.json、deepspeed_zero3_offload.json。7b 32k 长文本场景下若zero1OOM通常可依次尝试zero2、zero3必要时再叠加 offload 配置。6.2 在阿里云 DLC 中启动在阿里云 DLC 环境中需要先设置 NCCL 相关环境变量并拼接分布式训练所需的参数export NCCL_IB_TC136 export NCCL_IB_SL5 export NCCL_IB_GID_INDEX3 export NCCL_SOCKET_IFNAMEbond0 export NCCL_DEBUGINFO export NCCL_IB_HCAmlx5 export NCCL_IB_TIMEOUT22 export NCCL_IB_QPS_PER_CONNECTION8 export NCCL_NET_PLUGINnone export NCCL_BUFFSIZE2097152 export PYTORCH_CUDA_ALLOC_CONFmax_split_size_mb:512 - export EXP_NAMEdebug export EXP_NAMEyour_exp_name export PYTHONPATH.:$PYTHONPATH source ~/.bashrc cd /path/to/xtuner conda activate conda_env_name export NPROC_PER_NODE${KUBERNETES_CONTAINER_RESOURCE_GPU} export PORT${MASTER_PORT} export NNODES${WORLD_SIZE} export NODE_RANK${RANK} export ADDR${MASTER_ADDR} echo ${KUBERNETES_CONTAINER_RESOURCE_GPU} echo ${WORLD_SIZE} echo ${MASTER_PORT} echo ${MASTER_ADDR} echo ${RANK} xtuner train internlm2_7b_w_tokenized_dataset_copy.py \ --deepspeed deepspeed_zero1 \ --work-dir work_dirs/${EXP_NAME}其中${KUBERNETES_CONTAINER_RESOURCE_GPU}、${MASTER_PORT}、${WORLD_SIZE}、${RANK}、${MASTER_ADDR}均为 DLC 平台自动注入的环境变量分别用于推导单节点 GPU 数、分布式通信端口、总节点数、当前节点序号与主节点地址--work-dir指定训练日志与 checkpoint 的输出目录。6.3 训练过程中的观测模板 config 的custom_hooksL141-L156内置了三个实用 hookDatasetInfoHook打印数据集信息is_intern_repo_datasetTrue适配 intern_repo 格式EvaluateChatHook每隔evaluation_freq 500个 iter 用evaluation_inputs中英文各一条进行生成效果抽检实时观察对话能力ThroughputHook统计训练吞吐。由于use_varlen_attn True还会自动追加VarlenAttnArgsToMessageHubHook把变长注意力的参数传递到训练循环中。七、步骤 6转换模型格式训练得到的 deepspeed checkpoint 需要先转换为 HuggingFace 格式再转换为 Turbomind 格式用于部署/评测。DeepSpeed 转 HF$ python xtuner/tools/model_converters/pth_to_hf.py internlm2_7b_w_tokenized_dataset_copy.py /src/model/path /hf/dst/model/path其中三个位置参数依次为config 文件、DeepSpeed checkpoint 所在路径、HF 模型输出路径。从源码看pth_to_hf.py 会先用 meta device 初始化模型以节省内存量化模型等场景自动回退再通过guess_load_checkpoint加载权重并调用model.to_hf输出 HF 权重同时把 config 一并复制到输出目录xtuner_config.py方便追溯训练配置。它还支持--fp32默认 fp16、--max-shard-size默认 2GB 分片、--safe-serialization等可选参数。HF 转 Turbomind$ lmdeploy convert internlm2-chat-7b /hf/dst/model/path --dst-path /turbomind/dst/model/path该命令将 HF 权重转换为 Turbomind 推理引擎所需的格式其中internlm2-chat-7b是模型架构标识/hf/dst/model/path为上一步的输出目录。八、步骤 7Turbomind 评测模型转换为 Turbomind 格式后即可使用 OpenCompass 配合 LMDeploy 完成评测。具体评测环境准备与评测配置方法请参考仓库文档 docs/en/evaluation/opencompass.md 与 docs/zh_cn/evaluation/opencompass.md 中的说明原文档中引用的 OpenCompass LMDeploy 评测指引为外部文档此处以仓库内评测文档为准。需要说明的是原文档对应的是一套内部评测流程仓库内开放的通用评测方案更适合开源社区用户直接使用。九、总结与注意事项数据链路ftdp processed.jsonl→tokenize_ftdp_datasets.py离线 token 化 →chatml_llamav13_32k/{train,valid}下的.bin.bin.meta→load_intern_repo_tokenized_datasetPackedDataset加载训练。token 化阶段负数 token 表示不计算 loss的设计与训练阶段labels -100的还原逻辑是这条链路上最重要的对应关系。路径一致性--processed-dir必须是 ftdp 标准格式目录dataset_folder必须指向chatml_llamav13_32k/train步骤 1 与步骤 3 中的/path/to/tokenized/data必须是同一路径。可复现性建议通过get_data_order.py固化数据顺序并在 config 中设置data_order_path避免不同集群os.walk结果差异影响训练seed1024用于稳定 packing。显存策略use_varlen_attn Truebatch_size 1 32kmax_length是本模板的推荐组合OOM 时依次尝试deepspeed_zero2、deepspeed_zero3。断点续训开启save_optimizerFalse可只保存模型权重需mmengine0.10.3但代价是无法 resume。更多参考数据流与场景选择的整体流程图见 docs/zh_cn/user_guides/ftdp_dataset/README.md若你的场景是Processed 数据集 非 InternLM2 模型需为 tokenizer 补充 InternLM2 特殊 token可参考 docs/zh_cn/internevo_migration/ftdp_dataset/processed_and_others.rst。【免费下载链接】xtunerA Next-Generation Training Engine Built for Ultra-Large MoE Models项目地址: https://gitcode.com/GitHub_Trending/xt/xtuner创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考