类Jev项目Kev从入门到实战(5):如何训练:从数据构造到评测的完整管线

PART 5|如何训练:从数据构造到评测的完整管线

数据格式:一个 JSONL 搞定

一行一个请求,与 API 请求同形状,每个问题多一个 label:

jsonl 复制代码
{"state": {"subject": "Charged twice", "body": "I see two charges for order #4411."},
 "questions": {
   "team":     {"type": "choice", "instructions": "Which team should handle this ticket?",
                "criteria": {"billing": "Payments and refunds", "shipping": "Delivery problems", "access": "Login and account access"}, "label": "billing"},
   "angry":    {"type": "noul",   "instructions": "Is the customer angry?", "label": false},
   "priority": {"type": "score",  "instructions": "How urgent is this ticket?", "criteria": ["low", "normal", "high"], "label": 1}}}

choice 的 label 是选项名,noul 是 true/false,score 是等级序号(从 0 起)。留 10--20% 做评测。

最重要的一条:从 released checkpoint 出发要 --init_from

从底座 base 起训会把 Kev 已有能力全部扔掉。官方引用的一个实测:836 条支持工单数据上,base 起训在 Kev 自己的评测集掉到 0.33,而同样的数据 --init_from 保住 0.83 且新域到 0.88。

bash 复制代码
uv run python -m kev.train --data train.jsonl --base Qwen/Qwen3.5-4B-Base --init_from jaredpalmer/kev-4b \
    --epochs 2 --lr 2e-5 --batch 1 --accum 8 --dtype bf16 --checkpointing 1 --device cuda --out runs/mine

uv run python -m kev.benchmark --run runs/mine --data heldout.jsonl --out runs/mine-eval
uv run --extra serve python -m kev.serve --run runs/mine --port 8009

要点:--init_from 时学习率要降(2e-5 起步);--base 必须与 checkpoint 匹配(trainer 会校验底座、revision、LoRA rank、head size);--batch 1 --accum 8 bf16 下 0.8B 只要 4GB 显存。Mac 上一次只跑一个训练任务。

实战管线:我在知识图谱项目里的完整流程

复制代码
图谱元数据 ──▶ 自产训练数据(五任务,train/heldout/eval 三集样本严格不相交)
        │
        ▼
分段微调(Qwen3-0.6B-Base + LoRA r=16,lr 2e-4,bf16 + 梯度检查点,
          batch 1 × accum 8,state.json 记进度、任意中断零损失续跑)
        │
        ▼
统一评测(acc / confidence / ECE / AUROC / 延迟,同一把尺量所有模型)
        │
        ▼
kev.serve 接入业务决策层

数据构造四条纪律(比训练超参重要得多)

  1. 标签只取客观元数据,绝不用系统自身输出做标签------否则是自证循环(用共现分数标签训练,模型学到的就是你的召回偏置)。
  2. 任务设计成低基数(5 选 1 或二元)。高基数分类上,这类选项打分模型会塌------我测过 77 类的分类任务直接崩掉。
  3. 训练与运行的问题措辞逐字同源。强烈建议定义一个共享常量,两边 import,绝不复制粘贴。这是我从 0.400 到 1.000 的那条修正。
  4. 任务行数不均衡时,交错后必须洗牌。固定种子的 shuffle。我踩过的坑:数据不均衡 + 顺序交错,导致训练尾段 40% 全是同一任务,把另一个任务灾难性遗忘(0.925 → 0.215);等量数据时此 bug 完全不可见。

主结果

任务 零样本底线 微调后
朝代归属(5 选 1) 0.185(随机线 0.2) 0.925(AUROC 0.89,ECE 0.018)
下一跳选择(5 选 1,问法对齐后) 0.215 1.000(rank 对照 20/20)
作者归属(5 选 1) 0.145 0.32--0.34(AUROC 0.64)
体裁归属(5 选 1) 0.185 +0.000(选项描述口径缺陷所致)
作者判定(二元 noul) 0.475 0.6B 学不动(重设计数据后仍随机)

三个可迁移的结论:

  • 微调增益与任务性质强相关:纯形式可判的(朝代/体裁线索)增益大或受数据质量限制,需要实体知识的(作者判定)小模型学不动------先升级到 4B,或在 state 里注入知识,而不是加数据。
  • 零样本全随机是常态不是异常 :我在诗歌域测的多个类 Jev 模型(含 Kev)零样本全部落在随机线附近。这类模型的价值在微调之后,选型时别被零样本 demo 迷惑。
  • 评测口径要统一且固定:choice 看 picked==answer;noul 的 AUROC 用 Mann-Whitney U(逐阈值扫描在量化分数上会塌成 0);ECE 用 |mean(conf) − acc| 简化口径。所有模型同一份数据同一把尺。

LoRA 无 resume 的解法:分段训练

kev.train 的 --resume 只支持 full_ft 模式。LoRA 中断续跑的解法是把训练切成 N 段(--steps-per-seg),每段结束存 checkpoint,下一段 --init_from 上一段输出,外层脚本用 state.json 记进度------中断后重跑同一条命令即可续。每段约 5 分钟,对沙箱/CI 强杀长进程的场景零损失。

相关推荐
冬奇Lab3 分钟前
开源项目第243期:ArtCraft —— 给艺术家的 AI 创作 IDE,先搭场景再生成,把「抽卡」变成「手艺」
人工智能·开源
闽林致远3 分钟前
从文案语义到素材自动获取的工程链路-AutoVideoHub
人工智能
用户1917291270839 分钟前
无 API 老系统怎么让 Agent 接管:Computer Use 四层架构与可运行代码
人工智能
AICoder码农王18 分钟前
如何写 Skill 第8课,多 skill 体系治理:从治一个到治一片
人工智能
远离UE419 分钟前
半拉格朗日学习笔记 动力学 实时渲染
人工智能·算法
天远数科21 分钟前
Python数据工程:利用天远企业三要素验证优化大宗商品核心企业供应链入驻合规体验
人工智能
键道之下21 分钟前
便携标签机在墨西哥经销体系中的 App 交付责任怎么划分?
人工智能·智能手机·零售·智能硬件·智能硬件出海·硬件出海
长弓三石25 分钟前
钉钉与飞书机器人接入企业级智能体:过程及两份排障记录
人工智能
Apageoflove26 分钟前
把 ComfyUI 改造成无人值守视频产线:状态机、顺序锁与 ComfyUI 插件工程实践
人工智能·github
2601_9654542339 分钟前
开源项目发布会不用剪视频,AI一键生成宣传片
人工智能·音视频