ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

GPU 微调显存估算工具 canifinetune:数据格式避坑指南——JSONL 数据契约、多轮对话与截断规则详解

GPU 微调显存估算工具 canifinetune:数据格式避坑指南——JSONL 数据契约、多轮对话与截断规则详解

【免费下载链接】can-i-finetune-this

Estimate whether a Hugging Face model fits and fine-tunes on your local GPU.

项目地址:https://gitcode.com/gh_mirrors/ca/can-i-finetune-this
点击查看免费下载

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中,规则非常严格:

  1. 首条只能是system(可选)或user——直接以assistant开头会被拒绝;
  2. user / assistant 必须严格交替——连续两条 user、或缺少某一轮,都会报expected optional initial system, then alternating user/assistant;
  3. 对话必须以一条 assistant 回答结尾——训练目标是让模型学会"回答",没有结尾答案就没有监督信号;
  4. 每条content必须是非空字符串——空回答(如"")直接失败;
  5. 不支持 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 步避开数据格式的所有坑 ✅

  1. 定格式:有对话模板的 Instruct 模型用messages多轮格式(注意 5 条硬性规则),基座/无模板模型用instruction指令格式,一行只写一种;
  2. 控长度:默认truncation: error会让超长行现形,先清洗或调整seq_len(并重新估算显存),确需截断再显式开right;
  3. 看验收:跑完检查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.

项目地址:https://gitcode.com/gh_mirrors/ca/can-i-finetune-this
点击查看免费下载

相关推荐

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

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进