XTuner Llava 训练数据集离线处理指南:四步告别在线预处理耗时
发布时间:2026/9/18 7:46:18 作者:尧图编辑部 阅读量:1,286

XTuner Llava 训练数据集离线处理指南四步告别在线预处理耗时【免费下载链接】xtunerA Next-Generation Training Engine Built for Ultra-Large MoE Models项目地址: https://gitcode.com/GitHub_Trending/xt/xtuner导读本文讲解 XTuner 中 Llava视觉语言模型训练数据集的离线处理方案。当训练数据量非常大时每次训练前在线处理数据分词、映射对话格式、按模板组装 prompt会极为耗时甚至可能触发分布式训练中的超时问题。通过本指南你将掌握一套完整的四步流程导出 config、离线处理数据并保存至本地、修改 config 指向离线数据、直接启动训练让多次重复训练直接复用预处理结果显著缩短训练启动时间。为什么需要离线处理 Llava 数据XTuner 默认采用在线数据预处理策略即训练启动时通过process_hf_dataset对原始数据实时完成分词、对话映射与 prompt 模板组装得到训练所需的input_ids、labels等张量。这一策略降低了使用门槛但存在明显短板耗时集中在启动阶段数据量越大每次训练启动前需要等待的预处理时间越长且该过程为纯 CPU 任务可能触发nccl timeout在分布式训练中XTuner 由 rank0 统一完成预处理后通过torch.distributed.broadcast_object_list广播至其他 rank而该广播的超时时间与 nccl 通信超时时间相同默认 30 分钟。当训练集过大时rank0 可能无法在超时时间内处理完全部数据而导致报错详见 超大规模数据集 的说明。离线处理的思路是把数据处理这一一次性成本从每次训练中剥离出来——先对原始数据做一次完整的文本预处理并保存到本地磁盘之后无论训练多少次都直接读取这份已处理好的数据跳过重复计算。前置条件已正确安装 XTuner 及其依赖含datasets、transformers、mmengine等已准备 Llava 训练所需的原始数据包括JSON 格式的对话标注文件如llava_v1_5_mix665k.json或blip_laion_cc_sbu_558k.json对应的图片目录image_folder视觉编码器与 LLM 的预训练权重路径。已了解 Llava 训练 config 的基本结构可参考 xtuner/configs/llava 下的官方示例。Step 1导出模板 config 文件首先查看 XTuner 提供的所有与 Llava 训练相关的 configxtuner list-cfg -p llava该命令会列出仓库中所有文件名或路径匹配llava的配置文件。仓库当前提供的 Llava config 覆盖了多种模型组合例如llava_internlm2_chat_7b_clip_vit_large_p14_336_e1_gpu8_pretrain.pyInternLM2-Chat-7B CLIP ViT-Large/14-336预训练llava_internlm2_chat_7b_qlora_clip_vit_large_p14_336_lora_e1_gpu8_finetune.py同上QLoRA 微调以及基于 InternLM2-Chat-1.8B/20B、LLaMA3-8B/70B、Phi-3-mini、Vicuna-7B/13B 等底座的各种 pretrain/finetune 配置完整清单见 xtuner/configs/llava。找到需要使用的 config 名称下文以${CONFIG_NAME}指代后将其导出至当前目录xtuner copy-cfg ${CONFIG_NAME} .执行后当前目录会生成一个名为${CONFIG_NAME}_copy.py的副本文件与原配置内容完全一致后续所有修改都在这个副本上进行。Step 2离线处理数据集使用 XTuner 提供的专用工具脚本离线处理 Llava 训练数据中的文本部分python xtuner/tools/process_untokenized_llava_data.py \ ${CONFIG_PATH} \ --save-folder /folder/to/save/processed/dataset参数说明参数含义${CONFIG_PATH}Step 1 中导出的 config 文件路径即${CONFIG_NAME}_copy.py--save-folder离线处理后数据集的保存路径例如/folder/to/save/processed/dataset底层实现原理从源码看该脚本的核心逻辑非常简洁位于 process_untokenized_llava_data.py通过 mmengine 的Config.fromfile读取 config 文件调用BUILDER.build(config.train_dataloader.dataset)构建LLaVADataset实例——这一步会完整执行数据加载、dataset_map_fn对话映射、template_map_fn模板组装以及 tokenizer 分词等全部文本预处理取出llava_dataset.text_data属性即预处理完成后的 HuggingFace Dataset 对象调用text_data.save_to_disk(args.save_folder)将结果以磁盘数据集Arrow 格式形式保存。也就是说Step 2 实质上就是在训练之外单独执行了一遍在线预处理并把预处理产物持久化。注意这一步只处理文本数据input_ids、labels、图片路径引用等图片本身仍然以原始文件形式存放于image_folder训练时再按需读取。验证离线处理结果处理完成后可立即读取验证数据是否符合预期from datasets import load_from_disk ds load_from_disk(/folder/to/save/processed/dataset) print(ds)应能看到保存的 dataset 结构与原始text_data一致包含input_ids、labels、image等字段。Step 3修改 config 文件对 Step 1 导出的 config 做如下修改将数据源从在线处理切换为读取离线数据####################################################################### # PART 3 Dataset Dataloader # ####################################################################### llava_dataset dict( - data_pathdata_path, - tokenizertokenizer, offline_processed_text_folder/folder/to/save/processed/dataset ...)其中/folder/to/save/processed/dataset为 Step 2 中--save-folder指定的路径。修改后 config 中 LlavaDataset 的完整形态以仓库中 QLoRA 微调配置llava_internlm2_chat_7b_qlora_clip_vit_large_p14_336_lora_e1_gpu8_finetune.py为例修改后llava_dataset大致为llava_dataset dict( typeLLaVADataset, offline_processed_text_folder/folder/to/save/processed/dataset, image_folderimage_folder, image_processorimage_processor, dataset_map_fnllava_map_fn, template_map_fndict( typetemplate_map_fn_factory, templateprompt_template), max_lengthmax_length, pad_image_to_squareTrue)源码层面的行为说明从 llava.py 中LLaVADataset.__init__的实现可以看到构造时通过assert offline_processed_text_folder or (data_path and tokenizer)保证两种数据来源至少指定其一当设置了offline_processed_text_folder时直接调用load_from_disk(offline_processed_text_folder)加载文本数据不再执行data_path加载与process_hf_dataset分词流程这正是节省启动时间的关键若同时设置了offline_processed_text_folder与data_path源码会打印一条 WARNING提示将优先从offline_processed_text_folder加载数据if offline_processed_text_folder and data_path:分支图片的加载在__getitem__中按需完成根据text_data中的image字段通过Image.open(os.path.join(self.image_folder, image_file))读取并交给image_processor预处理为pixel_values没有图片的样本则填充全零张量。因此 config 中的image_folder必须保留并指向真实图片目录。此外LLaVADataset.modality_length属性用于LengthGroupedSampler的长度分组采样同样基于text_data计算离线加载后依然正常工作。Step 4开始训练使用 Step 3 修改得到的 config 直接训练即可。以预训练 configllava_internlm2_chat_7b_clip_vit_large_p14_336_e1_gpu8_pretrain.py为例# 单卡 xtuner train llava_internlm2_chat_7b_clip_vit_large_p14_336_e1_gpu8_pretrain_copy.py --deepspeed deepspeed_zero2 # 多卡torchrun NPROC_PER_NODE${GPU_NUM} xtuner train llava_internlm2_chat_7b_clip_vit_large_p14_336_e1_gpu8_pretrain_copy.py --deepspeed deepspeed_zero2 # 多卡slurm srun ${SRUN_ARGS} xtuner train llava_internlm2_chat_7b_clip_vit_large_p14_336_e1_gpu8_pretrain_copy.py --launcher slurm --deepspeed deepspeed_zero2其中--deepspeed deepspeed_zero2指定使用 DeepSpeed ZeRO-2 策略对应配置见 xtuner/configs/deepspeed 目录可选deepspeed_zero1、deepspeed_zero2、deepspeed_zero3及对应的 offload 版本。训练启动后数据加载阶段将直接读取磁盘上的预处理结果不再执行耗时的大规模分词。注意事项切换 tokenizer 或修改数据处理超参数后必须重新离线处理离线数据是某个 tokenizer 某组超参数下的产物。若更换了llm_name_or_pathtokenizer 随之变化或调整了单条数据的最大长度max_length、dataset_map_fn、template_map_fn等都必须重新执行 Step 2否则直接训练会因 token 序列与配置不匹配而报错image_folder仍需保留离线处理仅覆盖文本部分训练时图片依旧按image_folder实时加载因此该目录路径不能删除或改动磁盘占用save_to_disk以 Arrow 格式落盘数据量极大时注意预留足够的磁盘空间与纯文本模型的差异纯语言模型数据集的离线处理使用另一脚本xtuner/tools/process_untokenized_datasets.py其会额外生成*_modified.py配置文件并自动改写train_dataloader.dataset而 Llava 场景的process_untokenized_llava_data.py仅负责保存文本数据config 的改写需要按 Step 3 手动完成。两者的处理对象与流程不同使用时应加以区分。【免费下载链接】xtunerA Next-Generation Training Engine Built for Ultra-Large MoE Models项目地址: https://gitcode.com/GitHub_Trending/xt/xtuner创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考