GPU 微调显存估算工具 canifinetune:数据格式避坑指南——JSONL 数据契约、多轮对话与截断规则详解
【免费下载链接】can-i-finetune-this
Estimate whether a Hugging Face model fits and fine-tunes on your local GPU.
canifinetune 是一款面向单卡用户的GPU 微调可行性估算工具:它能在不下载模型权重的前提下,估算 LoRA / QLoRA 全量微调的 VRAM 显存预算,并生成可直接运行的训练配方(recipe)。但真正跑起来后,最常卡住新手的一步是微调数据格式。本文以 canifinetune 的 JSONL 数据契约为主线,详解两种数据格式、多轮对话的硬性规则与截断规则,帮你一次通过数据校验,避开微调数据准备中的高频坑。
1 分钟认识 canifinetune:先估显存,再备数据 🎯
在准备数据之前,建议先用 canifinetune 确认你的 GPU 能否承载目标模型和序列长度。它会把模型元数据、权重/梯度/优化器/激活值逐项相加,结合 RTX 4080 等真实校准数据,给出yes / tight / won't fit的结论和一个规划预算(GiB)。
这里有个容易被忽略的联动关系:数据里的seq_len会直接影响显存预算。如果为了迁就超长样本而调大序列长度,记得重新估算显存(参考 docs/quickstart.md 中的estimate命令)。
配方生成后,每个 recipe 文件夹都会自带一份"数据说明书"和示例数据:
- 数据格式契约:examples/qwen_1_5b_qlora_4080/dataset_format.md
- 示例数据:examples/qwen_1_5b_qlora_4080/data/sample.jsonl(4 条合成指令,仅用于跑通流程)
- 训练入口:examples/qwen_1_5b_qlora_4080/train.py
- 数据校验核心实现:src/canifinetune/training/data.py
JSONL 数据契约:一行一条,只有两种格式
canifinetune 的数据文件是标准 JSONL:每个非空行必须恰好是下面两种格式之一。空行会被统计跳过,坏行会带着行号直接报错,绝不静默丢行。
格式一:instruction 指令格式
三个字段:instruction(必填、非空)、output(必填、非空)、input(可选):
{"instruction":"Name a color.","input":"","output":"Blue."}处理细节(见 dataset_format.md.j2 模板):
- 数据会被拼成
### Instruction:/ 可选### Input:/### Response:三段式文本; - 整段只分词一次,不额外插入特殊 token,末尾补一个 EOS;
- 用 fast tokenizer 的字符偏移定位"答案起点",跨越提示/答案边界的 token 在 assistant 模式下会被屏蔽。
格式二:messages 多轮对话格式
一行里只有messages字段,不能与instruction/text等其他字段混用:
{"messages":[{"role":"system","content":"Be brief."},{"role":"user","content":"Name a color."},{"role":"assistant","content":"Blue."}]}它会直接套用模型 tokenizer 的原生 chat template渲染,不加生成提示、不额外补 BOS/EOS。
多轮对话数据避坑清单:5 条硬性规则 ⚠️
对话数据的校验逻辑写在 data.py 的validate_messages中,规则非常严格:
- 首条只能是
system(可选)或user——直接以assistant开头会被拒绝; - user / assistant 必须严格交替——连续两条 user、或缺少某一轮,都会报
expected optional initial system, then alternating user/assistant; - 对话必须以一条 assistant 回答结尾——训练目标是让模型学会"回答",没有结尾答案就没有监督信号;
- 每条
content必须是非空字符串——空回答(如"")直接失败; - 不支持 tool、多模态等其他角色——含工具调用或图片占位的数据会被明确拒绝。
另外两条容易踩的边界:
- 模型必须自带
chat_template才能用 messages 格式;没有对话模板的基座模型请改用 instruction 格式; - 一个文件里可以混排两种格式的行(第 3 行指令、第 4 行对话都行),只要每一行单独合法即可,这是官方明确允许的(见 docs/training.md)。
截断规则详解:默认errorvsright
这是新手踩坑重灾区。相关行为由配置中的两个参数控制,可在 examples/qwen_1_5b_qlora_4080/config.yaml 中看到默认值(seq_len: 1024、truncation: "error"):
| 参数 | 默认值 | 行为 |
|---|---|---|
truncation: error | ✅ 默认 | 超过seq_len的行直接报错,提示你增大seq_len或显式开启右截断 |
truncation: right | 需显式开启 | 从右侧截断到seq_len,但截断后必须仍剩有效回答 token,否则照样报错 |
三条关键认知:
- 默认不截断是保护,不是 bug:与其悄悄截掉一半数据,不如让你在数据阶段就发现问题;
- 长提示词吞掉答案 = 必挂:即使
loss_mode: all,只要截断后没有任何可监督的回答 token,也会报no response token remains(参见 test_training.py 中的用例); - 调大
seq_len后记得重估显存:序列长度直接进激活值显存预算(docs/troubleshooting.md 也提示了这一点)。
loss_mode:allvsassistant
loss_mode: all(默认):因果移位后监督所有非填充 token,提示词也参与训练。简单、通用,对话格式下不依赖模板的额外能力;loss_mode: assistant:只训练回答部分,提示词被屏蔽。指令格式靠 fast tokenizer 的偏移即可实现;对话格式则要求模板原生支持{% generation %}生成区间且 token 掩码可用——模板不支持时 would 明确报错,而不是"猜"边界。
一句话建议:拿不准就用默认的all+truncation: error,先跑通再优化。
常见踩坑速查表 📌
| 现象 / 报错线索 | 原因 | 解决办法 |
|---|---|---|
dataset line 12: record has 1523 tokens > seq_len=1024 | 行超长,默认truncation: error | 增大seq_len并重估显存;或刻意缩短文本;或显式设truncation: right |
expected optional initial system, then alternating user/assistant | 轮次顺序错(连续 user、以 assistant 开头等) | 修正对话顺序,确保结尾是 assistant |
messages cannot be mixed with text/instruction fields | 同一行混用了两种格式 | 一行一种格式 |
no response token remains after the causal shift | 截断后回答被完全吃掉 | 缩短提示词;不要指望靠截断"挤"出有效样本 |
| assistant 损失 + 无生成掩码的模板 | 模板不支持{% generation %}区间 | 改用loss_mode: all,或换支持掩码的模型/模板 |
| 空回答、空白 JSON 行 | 数据质量问题 | 按行号定位清洗;空行只统计、不训练 |
完整失败场景另见配方自带的 troubleshooting.md。
在哪里核对数据:run.json 与 dataset_format.md
训练跑完后,output/run.json会记录关键统计数据,帮助你确认数据被完整处理:
rows:有效训练行数blank_lines:跳过的空行数truncated_rows:被右截断的行数supervised_tokens:因果移位后实际参与监督的 token 总数dropped_rows:恒为 0——没有任何隐式丢行,也没有任何数据上传
对照配方里的 dataset_format.md,这份统计就是你的"数据验收单"。
总结:3 步避开数据格式的所有坑 ✅
- 定格式:有对话模板的 Instruct 模型用
messages多轮格式(注意 5 条硬性规则),基座/无模板模型用instruction指令格式,一行只写一种; - 控长度:默认
truncation: error会让超长行现形,先清洗或调整seq_len(并重新估算显存),确需截断再显式开right; - 看验收:跑完检查
run.json的行数与监督 token 数,确认没有意外截断或零监督样本。
数据契约的完整定义见 src/canifinetune/training/data.py 与 docs/training.md。格式对了,你的第一次本地微调就成功了一大半。
【免费下载链接】can-i-finetune-this
Estimate whether a Hugging Face model fits and fine-tunes on your local GPU.
相关推荐
MiniCPM-2B 微调实战:全量 SFT、LoRA/QLoRA 与多轮对话数据格式详解
MiniCPM 2B 微调实战:全量 SFT、LoRA/QLoRA 与多轮对话数据格式详解 本文是 OpenBMB MiniCPM 开源仓库中 finetune
人工智能大模型基础模型本地部署微调模型量化预训练openBMBFlora-Rewarder 输入数据完全指南:JSONL 格式、多视角相机与视频对齐避坑
Flora Rewarder 输入数据完全指南:JSONL 格式、多视角相机与视频对齐避坑 Flora Rewarder 是 NVIDIA 开源的机器人视频奖励
人工智能大模型基础模型具身智能机器人多模态VoxCPM微调数据准备指南:JSONL清单格式、音频规格与常见坑位一文讲清
VoxCPM微调数据准备指南:JSONL清单格式、音频规格与常见坑位一文讲清 🎙️ 本文将带你系统掌握 VoxCPM 微调数据准备 的完整流程:如何编写 JS
人工智能大模型语音音频微调
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考