news 2026/10/22 3:31:40

torchtune 数据集五类数据一次讲透:从本地 csv 到训练的完整接入指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
torchtune 数据集五类数据一次讲透:从本地 csv 到训练的完整接入指南

torchtune 数据集五类数据一次讲透:从本地 csv 到训练的完整接入指南

【免费下载链接】torchtunePyTorch native post-training library项目地址: https://gitcode.com/GitHub_Trending/to/torchtune

torchtune 是 PyTorch 官方的后训练框架,它的数据集(dataset)体系决定了你的数据能不能顺利进模型。本文带你从一份本地 csv 出发,快速打通 torchtune 数据集的完整接入链路,覆盖 instruct、chat、DPO、持续预训练、多模态五类形态,讲清SFTDataset的三插槽设计、-100标签成因与常见踩坑,最后给一份可直接照做的接入清单。

一、一份本地 csv,三行接进训练

先拿到正反馈,再谈原理。假设你手里只有一个本地 csv,两列:question和answer,想让它喂给 torchtune 做 LoRA 微调。最短路径就三步:准备数据 → 建 tokenizer → 调instruct_dataset。

数据文件长这样(两列、表头即列名):

# data/support.csv # question,answer # 巴黎是哪个国家的首都?,法国。 # 世界上最高的山峰是什么?,珠穆朗玛峰。

建一个 tokenizer,再调 builder,跑通就算成功一半:

from torchtune.models.qwen3 import qwen3_tokenizer from torchtune.datasets import instruct_dataset tok = qwen3_tokenizer(path="/tmp/Qwen3-0.6B/vocab.json", merges_file="/tmp/Qwen3-0.6B/merges.txt", max_seq_len=4096) ds = instruct_dataset(tokenizer=tok, source="csv", data_files="data/support.csv", column_map={"input": "question", "output": "answer"}, train_on_input=False, split="train") print(tok.decode(ds[0]["tokens"])) print(ds[0]["labels"]) # 用户问句部分全是 -100,只有答案参与 loss

这里有个点值得记:instruct_dataset默认找input/output两列,你的列名是question/answer,就用column_map={"input": "question", "output": "answer"}把「预期列名 → 真实列名」对上去。

在 recipe 的 YAML 里同样这么写(tokenizer 由 recipe 传入,dataset 内不用重复):

dataset: _component_: torchtune.datasets.instruct_dataset source: csv data_files: data/support.csv column_map: input: question output: answer train_on_input: False split: train

从 recipes/configs/qwen3/0.6B_lora_single_device.yaml 这类真实配置能看出,内置 builder(如alpaca_cleaned_dataset)和自定义 builder 都能挂在这个dataset:槽位下。跑通这一步,说明加载、分词、组标签这条链已经通了。

二、把数据流拆成四层看

换个视角,把流水线当工厂工序。torchtune 所有数据集都走同一条线,可以拆成四层,每层只回答「解决什么问题、输入输出是什么」。这样比背四阶段更容易落地。

  • 数据加载层:解决「数据从哪来」。SFTDataset.__init__把数据加载完全委托给 Hugging Face 的load_dataset——source传 HF 仓库名就从 Hub 拉,传"json"/"csv"/"text"再配data_files就读本地或 https 远程文件;**load_dataset_kwargs(如split、name)原样透传。可选filter_fn/filter_kwargs在预处理前过滤低质量样本。输入是配置,输出是一个 HF Dataset 对象。
  • Message 标准化层:解决「任意格式怎么对齐」。message_transform把一行原始样本转成Message列表——统一成system/user/assistant/ipython四种角色的「对话」。这是全体系的地基,torchtune/data/_messages.py 里InputOutputToMessages、ShareGPTToMessages、OpenAIToMessages、ChosenRejectedToMessages就是各形态的转换器。输入是原始 dict,输出是{"messages": [Message, ...]}。
  • 模型转换层:解决「怎么变成模型能吃的 token」。model_transform做分词、prompt 模板、图像变换等模型专属处理;文本任务直接把 tokenizer 当model_transform用。它的契约很硬:必须返回tokens和mask两个键,否则抛ValueError。输入是 Message 列表,输出是tokens/mask(多模态还多encoder_input)。
  • 组批层:解决「怎么拼成 batch」。collater 做 padding 与 batch 组装,实现在 torchtune/data/_collate.py:padded_collate_sft(通用 SFT)、padded_collate_tiled_images_and_mask(多模态 tile 图)、padded_collate_packed(打包样本)、padded_collate_dpo(偏好对)。recipe 按数据集类型选对应 collater。

真正的「逐样本执行」发生在SFTDataset.__getitem__内部组装的SFTTransform里(见 torchtune/datasets/_sft.py):先跑message_transform并validate_messages校验,再跑model_transform,最后由mask生成labels。这段正好解释了下一节的高频疑问。

三、五种数据形态,各找入口

数据长什么样,就用哪个入口。不再逐个任务长篇展开,统一用「数据长什么样 → 用哪个入口函数 → 关键字段怎么填」的三段式压缩呈现。

单轮文本(instruct)

数据是「一问一答」两列结构。入口instruct_dataset。关键字段:column_map(列名对齐)、train_on_input(用户问句是否计入 loss,默认 False)、new_system_prompt(给每条样本前置一条 system 消息)。内部由InputOutputToMessages完成 Message 组装。

多轮对话(chat)

数据是一个conversations/messages列,里面是 user-assistant 多轮来回。入口chat_dataset。关键字段:conversation_column(对话列名)、conversation_style(只支持sharegpt或openai两种,对应ShareGPTToMessages/OpenAIToMessages)、new_system_prompt。sharegpt 格式是{"from": "human"|"gpt", "value": ...},openai 格式是{"role": "user"|"assistant", "content": ...}。

from torchtune.datasets import chat_dataset ds = chat_dataset(tokenizer=tok, source="json", data_files="data/talk.json", conversation_column="dialogue", conversation_style="openai", train_on_input=False, split="train")

偏好对(DPO)

数据是同一 prompt 下 chosen/rejected 两条回复,服务于 DPO 训练。入口preference_dataset。关键字段:column_map={"chosen": "...", "rejected": "..."}、train_on_input、new_system_prompt。它只接受 openai 风格对话,输出四组张量chosen_input_ids/chosen_labels/rejected_input_ids/rejected_labels,prompt 段全被 mask 成-100,只有 assistant 回复参与 loss——这正是 DPO 对比学习要的输入形态,batch 层用padded_collate_dpo组装。注意:偏好数据集不支持packed,设 True 会抛ValueError。

纯文本语料(持续预训练)

数据只含一个文本列,自监督微调基座。入口text_completion_dataset。关键字段:column(文本列名,默认text,本地 txt 直接用默认即可)、add_eos(默认 True)、split_across_pack。这是格式最简单的一类——不用 Message,直接tokenizer.encode后把 labels 右移一位、末尾补-100。

图文(多模态 VLM)

数据是 sharegpt 对话 + 一列图像路径,文本里含<image>占位符。入口multimodal_chat_dataset。关键字段:column_map(把对话列和图像列对齐,默认conversations/image)、image_dir(相对路径前缀)、image_tag(占位符,默认<image>)。一个样本目前支持单张图,且总是插到第一条 user 消息;图像会切成 tile,形状如[4, 3, 224, 224]。多模态数据集同样不支持packed。

from torchtune.datasets.multimodal import multimodal_chat_dataset from torchtune.models.llama3_2_vision import llama3_2_vision_transform mt = llama3_2_vision_transform(path="/tmp/.../tokenizer.model", prompt_template="torchtune.data.QuestionAnswerTemplate", max_seq_len=8192, image_size=560) ds = multimodal_chat_dataset(model_transform=mt, source="json", data_files="data/vqa.json", column_map={"conversations": "dialogue", "image": "img"}, image_dir="/data/vqa/", image_tag="<image>", split="train")

一张表收尾

数据形态入口 builder数据长什么样关键字段
单轮文本instruct_dataset两列一问一答column_map、train_on_input、new_system_prompt
多轮对话chat_dataset一个对话列conversation_column、conversation_style
偏好对preference_datasetchosen/rejected 对话column_map、train_on_input(不支持 packed)
纯文本语料text_completion_dataset单文本列column、add_eos、split_across_pack
图文multimodal_chat_datasetsharegpt 对话 + 图像列column_map、image_dir、image_tag(不支持 packed)

四、schema 对不上,自己写 transform

内置 builder 装不下时,补最后一块拼图。当你的列结构/媒体结构无法被上面任何 builder 覆盖时,官方推荐做法是「自定义 message transform +SFTDataset」两件拼。

from torchtune.data import Message from torchtune.modules.transforms import Transform from torchtune.datasets import SFTDataset class MyTransform(Transform): def __call__(self, sample): return {"messages": [ Message(role="user", content=sample["q"], masked=True, eot=True), Message(role="assistant", content=sample["a"], masked=False, eot=True), ]} def my_dataset(tokenizer, **kw): return SFTDataset(source="json", data_files="data/my.json", split="train", message_transform=MyTransform(), model_transform=tokenizer, **kw)
dataset: _component_: data.dataset.my_dataset

masked=True/False直接决定哪些 token 计入 loss(对应-100逻辑);eot=True表示消息后追加结束符。多模态场景把图像对象放进Message的 content,model_transform换成对应 VLM 的 transform 即可。

五、这几个坑,先知道不翻车

集中排雷,省你调试时间。

  • labels里的-100从哪来:Message.masked=True会传导成 token 级mask,SFTTransform把mask=True的位置替换成CROSS_ENTROPY_IGNORE_IDX(即-100,定义在 torchtune/data/_common.py)。默认用户问句被 mask,所以不进 loss;且 labels 相对 logits 右移一位、末尾再补一个-100。
  • train_on_input与 mask 的关系:它就是控制 user 消息 mask 与否的开关。较新的实现里它已被masking_strategy取代(train_on_assistant/train_on_all/train_on_last),同时传时以masking_strategy为准——train_on_input=True等价于train_on_all。注意多模态下 user 消息恒被 mask。
  • column_map对齐规则:键永远是「预期列名」(input/output、chosen/rejected、conversations/image),值才是你数据里的真实列名;写反了会直接ValueError。
  • Message媒体内容只接受图像对象本身:要传load_image(torchtune/data/_utils.py)产出的图像,不能只塞文件路径或 URL。multimodal_chat_dataset里的image_dir帮你拼完整路径,image_tag负责占位符↔图像的交错。
  • packed有门槛:设packed=True要求 tokenizer 的max_seq_len已配置,且偏好/多模态数据集根本不支持 packing。
  • split可取子集:默认"train",也能写"train[:10%]"这种 HF 语法快速调试。

六、从 0 到 1 接入清单

照着勾完,数据就进场了。

  1. 定形态:单轮 →instruct_dataset;多轮 →chat_dataset;偏好 →preference_dataset;纯文本 →text_completion_dataset;图文 →multimodal_chat_dataset;都对不上 → 自定义SFTDataset+ transform。
  2. 定来源:HF 仓库名传source;本地/远程文件传文件类型 +data_files;需要子集用split。
  3. 对齐列名:按各 builder 的预期列名填column_map/conversation_column/column。
  4. 控 loss 范围:用train_on_input(或masking_strategy)决定 user 是否进 loss,检查labels的-100分布是否符合预期。
  5. 配 tokenizer/transform:文本用ModelTokenizer当model_transform;多模态用对应 VLM transform,并设image_dir/image_tag。
  6. 选 collater:recipe 里按数据集类型挂padded_collate_sft/padded_collate_dpo/padded_collate_tiled_images_and_mask/padded_collate_packed。
  7. 想提速再开packed:确认 tokenizer 已设max_seq_len、且任务支持 packing。

顺带一提,torchtune.datasets还内置了一批开箱即用的 builder——alpaca_dataset/alpaca_cleaned_dataset、grammar_dataset、samsum_dataset、slimorca_dataset、hh_rlhf_helpful_dataset、stack_exchange_paired_dataset、cnn_dailymail_articles_dataset、wikitext_dataset,以及组合工具ConcatDataset(多源拼接)和PackedDataset(样本打包);多模态侧另有the_cauldron_dataset、llava_instruct_dataset。它们本质都是上面这套「source+message_transform+model_transform」插槽的预填组合——理解这条线之后,选数据集、改列名、控 loss、写任意 schema 的自定义 pipeline,都能在同一套思路下完成。

【免费下载链接】torchtunePyTorch native post-training library项目地址: https://gitcode.com/GitHub_Trending/to/torchtune

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 9:49:07

EMC vnx5300更换硬盘及SPA/B电源更换

故障 查看 VNX 存储硬盘外观指示灯有黄灯告警&#xff1b;登入 VNX 存储管理软件 Unisphere 查看告警信息查看 Unisphere 管理软件系统硬件信息&#xff0c; System →Hardware →Storage Hardware&#xff0c; 在 Disk 下面有红色 F 告警&#xff0c; 状态为 Removed。更换硬盘…

作者头像 李华
网站建设 2026/10/21 3:42:18

soap协议

1.何为SOAP xml http rpc soap 基于 xml 定义的一种协议&#xff0c;用于传递结构化数据 xml子集 领域特化soap 可以绑定 http/tcp/udp等通信协议&#xff0c;以此完成网络通信最常见的soap应用场景&#xff0c;利用http完成soap消息的交互&#xff0c;达成rpc交互过程简单理解…

作者头像 李华
网站建设 2026/10/19 8:40:40

RK平台android12 动态调整屏幕方向

RK平台 Android12 动态调整屏幕方向&#xff08;persist 属性方案&#xff0c;免重新编译&#xff09;适用场景&#xff1a;RK 平台 Android 12 / Android 14&#xff0c;整机为固定安装方向&#xff08;竖屏广告机、工控一体机、自助终端、门禁机等&#xff09;&#xff0c;无…

作者头像 李华
网站建设 2026/10/19 3:02:34

Autoware.Universe 样例运行:高精地图部署到 ~/autoware-map 与排错指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/21 18:55:54

MFC与Halcon图像显示桥接:窗口句柄绑定与双缓冲实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/21 7:29:39

Linux进程并发设计:从fork()到wait()的底层原理与工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华