370 lines
18 KiB
Markdown
370 lines
18 KiB
Markdown
---
|
||
name: model-iteration
|
||
description: 小爱中控模型自主迭代框架(autoresearch-zk)。用于对小爱同学中控理解调度模型进行假设驱动的自主 SFT+评测迭代循环。触发信号:用户发送"开始,需求集合名"(如"开始,icl_test")时,必须立即使用此 skill 启动迭代,不得自行发挥。任何涉及 cml 评测、zk 模型训练、数据增强、badcase 分析、augment_*.jsonl 生成的任务,也应使用此 skill。
|
||
when_to_use: |
|
||
用户表达以下任一意图时启用此 skill:
|
||
- 直接的核心触发短语:「开始,<需求集合名>」(如「开始,icl_test」)
|
||
- 自然语言的训练/迭代请求:「我要进行模型训练」「开始模型训练」「目标集合是 xxx」「跑一下需求集合 xxx」「迭代 xxx」「针对 xxx 做模型迭代」
|
||
- 平台运维:「评测当前模型」「分析 badcase」「Gold drift 检查」「数据增强 augment_*.jsonl」「提交 SFT 训练」「跑 CML workflow」「写 iteration_log」
|
||
- 关键词:CML 评测 / SFT / autoresearch / zk 中控理解调度 / requirement set / specific test / metric_diff / lark_template
|
||
无需用户严格按「开始,xxx」字面匹配;只要意图涉及小爱中控模型 SFT+评测迭代,就立刻使用此 skill。
|
||
---
|
||
|
||
# autoresearch-zk — 小爱中控模型自主迭代框架
|
||
|
||
## 🚫 严禁问用户的事(违反任一条 = 违反 skill)
|
||
|
||
每次问用户都让用户烦。program.md 已经把"什么时候停"写得很死(17 类 HiTL 信号 + 用户主动打断),**这之外一律不准停下来等确认**。下面是被反复踩坑的"擅自暂停"模式,**全部禁止**:
|
||
|
||
| ❌ 禁止说的话 | ✅ 正确做法 |
|
||
|---------|---------|
|
||
| "要不要我做训练集近邻检索?" | 这是 §2.3 分析必做项,**直接做**,做完把结果落 report |
|
||
| "下一步可以继续吗?" | 永远不问。看 program.md 流程图自己判断 |
|
||
| "我先把控制权交回,等你来问跑完了吗" | watcher 接手 UI 同步,你还是要在 bash 内 sleep+poll 等 cml 完,看到 complete **直接进 Step 1** |
|
||
| "这一步是关键决策点,需要你拍板" | program.md 没写就不是。**自主决策 + 落 iteration_log** |
|
||
| "我把现状停在这里,把决策摘要给你 review" | 不准。摘要可以写,但不准停 |
|
||
|
||
**合法暂停只有**:
|
||
|
||
1. program.md `## Human-in-the-Loop 时机` 章节的 7 类迭代级信号
|
||
2. `### 训练集调整专项 H-i-T-L 信号` 的 T1-T10
|
||
3. **§4.0.1 Step B 量级判定的 HiTL 分支**:
|
||
- 候选量 51-200 条 → **必须**抽样 30-50 条到飞书 sheet 让人审 1/0,按比例外推(**这就是一次合法暂停**,不是擅自停)
|
||
- 候选量 >200 条 → 命中触发条件 #3,强制 HiTL 介入让人定更精细 pattern 收窄
|
||
4. 用户主动发消息打断
|
||
|
||
这之外**所有**"我觉得这事大、我先停"的本能都要压下来。命中合法暂停时,**不要只是说"等你确认"**——按 §4.0.1 把抽样表/精细 pattern 的具体输出 dump 到飞书 / scratchpad 给人具体可审的东西,再停。
|
||
|
||
## 📋 每个 Step 的强制准入条件(少一项不准进下一步)
|
||
|
||
按 Step 编号,**进入下一 Step 前**必须把当前 Step 的准入清单全部完成并落到 state file / iteration_log,否则视为跳步违规。
|
||
|
||
### Step 0 准入
|
||
- [ ] cml 环境检查通过(`which cml` + `cml config show`)
|
||
- [ ] runDic 已分配(扫 `run_history_dir` 取 max+1)
|
||
- [ ] CML workflow 已提交(拿到 Execution ID)
|
||
- [ ] watcher 声明已写入 program-state.jsonl
|
||
- [ ] 在 bash sleep+poll 等到 cml=complete
|
||
|
||
### Step 1 准入(`dist-analysis`)
|
||
- [ ] 读 `metric_diff/lark_template.json` 提分层指标(specific / 大盘车载 / 目标专项)
|
||
- [ ] 读 `metric_diff/specific_comparison.csv` 抽 baseline 错误分布
|
||
- [ ] **§2.3 失败 case 与训练数据的关联**:每条错例在 `train_set/zk_intent/*.jsonl` 做近邻检索(前 3 近邻),输出"有近邻 / 无近邻"分类
|
||
- [ ] **§2.3 Reward 对齐检查**:抽 10 条失败 case 用 `zk_reward_fn` 验 reward 方向
|
||
- [ ] §0.1 Gold drift 检查(如未做)
|
||
|
||
### Step 2 准入(`report`)
|
||
- [ ] §2.4 根因归类表(每个 pattern 必归一类,可并列但要主次)
|
||
- [ ] 写入 `results/workflow<runDic>.md`
|
||
- [ ] error_registry 追加本轮错误
|
||
|
||
### Step 3 准入(`hypothesis`)
|
||
- [ ] 写本轮假设到 iteration_log.jsonl 的 hypothesis 字段
|
||
- [ ] 假设必须有依据(指向 §2.3 / §2.4 的具体发现)
|
||
|
||
### Step 4 准入(`augment`,需要修改训练集才进)
|
||
- [ ] **§4.0 原始训练数据清洗(增强前必做)**——按 4 种动作走完逐 pattern 判定
|
||
- [ ] §4.0.1 Step A:候选定位输出 csv,**不直接改**
|
||
- [ ] §4.0.1 Step B:量级判定走对应支线(≤50 自动 / 51-200 抽样审 / >200 触发 #3)
|
||
- [ ] §4.0.1 Step C:备份 `.bak` 文件
|
||
- [ ] §4.1 输入准备 / §4.2 GPT 调用 / §4.3 sanity check / §4.4 写入
|
||
|
||
### Step 5 准入(`sft`)
|
||
- [ ] 旧 sft_output 已 `mv sft_output sft_output_r{prev}` 备份
|
||
- [ ] 训练参数从 config.yaml 读,model_path = basemodel(**不从上轮 ckpt 续训**)
|
||
|
||
### Step 6 准入(`log`)
|
||
- [ ] iteration_log.jsonl 完整 schema(hypothesis / intervention / prediction / results / verdict / root_cause_findings / error_delta / next_hypothesis)
|
||
|
||
### 跳步检查
|
||
|
||
每次写 `{step:"X","status":"running"}` 前,**先看 state file 上一条 step 是不是 complete**。如果上一条还在 running 或者跳过了某个 Step,**回去补**,不要往前走。
|
||
|
||
## ⚠️ Pipeline UI 同步约定(强制,必读)
|
||
|
||
**平台用户实时盯着 pipeline UI 看你跑到哪一步**。卡片状态完全靠你写 `program-state.jsonl` 驱动;**你不写、卡片不动;你嘴上说 running、文件里写 failed,UI 就显示 failed**。所以下面这些是**硬性纪律,不是建议**:
|
||
|
||
### R1(最重要)— 每一次状态切换都必须先 echo 再做事
|
||
|
||
进入新 step 之前,**第一件事**就是 append 一行 `running`。完成后**最后一件事**是 append 一行 `complete`。失败时也必须 append `failed`。**永远不要"嘴上"宣布状态切换却没落盘**。
|
||
|
||
错误示范(你不许这样):
|
||
> 我现在开始 step 0,跑 CML 评测... \[执行很多操作\]... 已完成 ✅
|
||
|
||
正确示范:
|
||
> ```bash
|
||
> echo '{"step":"cml","status":"running","ts":"'$(date -Iseconds)'"}' >> "$SESSION_OUTPUT/program-state.jsonl"
|
||
> ```
|
||
> *(然后才执行 step 0 的具体操作)*
|
||
> ...
|
||
> ```bash
|
||
> echo '{"step":"cml","status":"complete","ts":"'$(date -Iseconds)'"}' >> "$SESSION_OUTPUT/program-state.jsonl"
|
||
> ```
|
||
|
||
### R2 — 写入即生效,最后一行覆盖前面
|
||
|
||
后端按 `step` 字段取**最后一条**状态。如果你之前写过 failed、现在恢复了,**必须 append 一条新的 `running`**,否则 UI 永远停在 failed。
|
||
|
||
### R3 — Step 之间不允许跳步骤而不留状态
|
||
|
||
进入 dist-analysis 前必须确认 cml 状态已写到 `complete`(或显式 `failed` 后用户决定继续)。
|
||
|
||
### R4 — 中长任务用 progress 字段更新
|
||
|
||
CML 评测、SFT 训练这种几分钟以上的任务,**每次轮询/心跳时附带 progress 字段**写一条新的 `running` 行(旧 running 不需删,最后一行最新):
|
||
|
||
```bash
|
||
echo '{"step":"cml","status":"running","progress":0.4,"ts":"'$(date -Iseconds)'"}' >> "$SESSION_OUTPUT/program-state.jsonl"
|
||
```
|
||
|
||
UI 卡底部进度条会跟着动;不写就一直显示初始进度。
|
||
|
||
### State 文件位置
|
||
|
||
```
|
||
<当前会话目录>/output/program-state.jsonl
|
||
```
|
||
|
||
会话目录在系统提示的 `[当前会话目录]` 里给了绝对路径。**直接用那个值**,不要拼。**绝对不要**写到 `/mnt/wangsenhao/...` 或项目根目录——多会话互相覆盖。
|
||
|
||
每次写之前先确保目录存在:
|
||
|
||
```bash
|
||
SESSION_OUTPUT="<从系统提示拷过来>/output"
|
||
mkdir -p "$SESSION_OUTPUT"
|
||
```
|
||
|
||
### Step key 表(必须用这套 key,否则匹配不到卡片)
|
||
|
||
| step key | 对应卡片 |
|
||
|----------|----------|
|
||
| `cml` | CML 评测 |
|
||
| `gold-drift` | Gold Drift |
|
||
| `dist-analysis` | 分层结果分析 |
|
||
| `report` | 问题分析 & 报告 |
|
||
| `hypothesis` | 形成假设 |
|
||
| `augment` | 数据增强 |
|
||
| `verify` | 修改返回验证 |
|
||
| `sft` | SFT 训练 |
|
||
| `log` | 记录迭代日志 |
|
||
| `next-round` | 下一轮评测 |
|
||
|
||
### KPI(你不要写,后端读权威源)
|
||
|
||
顶部 7 个 KPI(RUN ID / VERSION / 目标集合 / 大盘车载 / SPECIFIC TEST / ITERATION / 耗时)由后端从权威源直接读取:
|
||
|
||
| KPI | 后端读取自 |
|
||
|-----|-----------|
|
||
| RUN ID | `RUN_HISTORY_DIR`(默认 `/mnt/xiaoai-zk-model-train-tj5/workflow5/`)下 `workflow<N>/` 取 max N |
|
||
| VERSION | `skills/model-iteration/assets/config.yaml` 的 `cml_eval.version` |
|
||
| 目标集合 | 从 session 最新 user 消息里解析 `"开始, <name>"` 中的 name |
|
||
| 大盘车载 / SPECIFIC TEST | `RUN_HISTORY_DIR/workflow<runDic>/metric_diff/lark_template.json` |
|
||
| ITERATION | `<AUTORESEARCH_ROOT>/results/iteration_log.jsonl` 行数 |
|
||
| 耗时 | program-state.jsonl 第一条 `{step:"cml",status:"running"}` 的 `ts` 到现在 |
|
||
|
||
**你不要再写 `{"kpi":...}` 行**——写了也会被后端忽略,不显示。如果想让用户看到某个 KPI 的当前值,把它落到对应的权威源(比如改 config.yaml、写 iteration_log),后端会自动读到。
|
||
|
||
### Watcher(长任务的 UI 状态副车,**不是给你交回控制权的借口**)
|
||
|
||
CML 评测 / SFT 训练这类几分钟到几十分钟的长任务,声明 watcher 让**后端自动检测产物文件并把 `step=complete` 写到 state file**——这样 UI 的卡片状态不依赖你主动写 complete,watcher 替你写。
|
||
|
||
但你**仍然必须留在当前迭代里继续干活**,遵守 program.md 里的 **NEVER STOP / 全程不打断用户** 原则:
|
||
|
||
- **不许**给用户回"控制权交回 / 我先停下 / 等你来问"这种话
|
||
- **不许**主动结束本轮(除非命中 program.md 里写明的 H-i-T-L 阻断信号)
|
||
- 提交完任务、声明完 watcher 后,**继续在 bash 里轮询 state file** 等 cml=complete,看到就**直接进入 Step 1**(读 metric_diff、做分层分析、写报告等),一气呵成跑完整轮迭代
|
||
|
||
watcher 解决的是 **UI 与 agent 异步**:UI 不用等 agent 写状态,watcher 替 agent 把 complete 落盘。它不是替你"放假"。
|
||
|
||
格式:
|
||
|
||
```bash
|
||
# 进入 step 时按规则写 running
|
||
echo '{"step":"cml","status":"running","ts":"'$(date -Iseconds)'"}' >> "$SESSION_OUTPUT/program-state.jsonl"
|
||
|
||
# 紧接着声明 watcher:当目标文件出现 → 后端自动写 cml=complete
|
||
echo '{"watch":{"step":"cml","kind":"file_exists","path":"/mnt/xiaoai-zk-model-train-tj5/workflow5/workflow17782/metric_diff/lark_template.json","interval":30,"timeout":3600,"run_id":"R0"}}' >> "$SESSION_OUTPUT/program-state.jsonl"
|
||
```
|
||
|
||
字段:
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `step` | ✅ | 跟卡片 step key 一致(cml / sft / augment ...) |
|
||
| `kind` | ✅ | 当前只支持 `file_exists` |
|
||
| `path` | ✅ | 目标文件**绝对路径**。文件出现就视为 step 完成 |
|
||
| `interval` | ⭕ | 轮询间隔秒,默认 30,最小 2 |
|
||
| `timeout` | ⭕ | 整体超时秒,默认 3600,超时写 failed |
|
||
| `run_id` | ⭕ | 写入 Live Log 时的 iter 标签 |
|
||
|
||
**watcher 资源管理**:
|
||
- 同一 (session, step) 已有 watcher 在跑时,重复声明被忽略
|
||
- step 已经有 complete/failed 行后,watcher 声明会被忽略
|
||
- 后端 scanner 5 秒扫一次所有会话的 state file
|
||
|
||
**典型用法**(CML workflow,**NEVER STOP**):
|
||
|
||
```bash
|
||
# 1. 提交 cml 任务(异步,立刻返回 runDic)
|
||
RUNDIC=$(cml workflow run --workflow_id "$WORKFLOW_ID" ...)
|
||
|
||
# 2. 写 running + watcher 声明
|
||
echo '{"step":"cml","status":"running","ts":"'$(date -Iseconds)'"}' >> $S
|
||
echo '{"watch":{"step":"cml","kind":"file_exists","path":"'$ROOT/workflow$RUNDIC/metric_diff/lark_template.json'","interval":30,"timeout":7200,"run_id":"R'$N'"}}' >> $S
|
||
|
||
# 3. 跟用户简报一句状态,**不要说"交回控制权"**,紧接着开始等
|
||
echo "已提交评测 runDic=$RUNDIC,开始轮询 state file 等 watcher 写 complete..."
|
||
|
||
# 4. 在 bash 里轮询 state file(不阻塞你下一步思考)
|
||
while true; do
|
||
status=$(grep -E '"step":"cml"' $S | tail -1 | python3 -c 'import json,sys; print(json.loads(sys.stdin.read()).get("status",""))')
|
||
if [ "$status" = "complete" ]; then break; fi
|
||
if [ "$status" = "failed" ]; then echo "cml failed"; exit 1; fi
|
||
sleep 60
|
||
done
|
||
|
||
# 5. cml 完成 → 立刻进入 Step 1,读 metric_diff、做分析、写下一步 running...
|
||
# 整轮迭代不交回控制权,直到达标 / 命中 H-i-T-L 阻断 / 用户主动打断
|
||
```
|
||
|
||
### Live log(可选)
|
||
|
||
要把日志推到 UI 底部那块黑色 Live Log 区,追加:
|
||
|
||
```bash
|
||
echo '{"log":{"ts":"11:55:10","iter":"R3","text":"Step 3 开始: 问题分析 & 报告生成"}}' >> "$SESSION_OUTPUT/program-state.jsonl"
|
||
```
|
||
|
||
### 不要做的事
|
||
|
||
- **不要**写 program.md(旧机制已废弃,写了也没用,平台现在不读它)。
|
||
- **不要**把 state 文件写到 `/mnt/wangsenhao` 或仓库根目录——只写当前会话的 `output/program-state.jsonl`。
|
||
- **不要**用与上表不一致的 step key(比如 `step:"评测"`、`step:"step0"`),UI 匹配不到。
|
||
- **不要**重写整个文件(每行只追加,append 即可),重写会导致 UI 闪。
|
||
|
||
## 快速参考
|
||
|
||
| 项目 | 值 |
|
||
|---|---|
|
||
| 触发信号 | `"开始,<需求集合名>"` |
|
||
| 评测 workflow | `f-20260408161444-wu3pz`(版本见 `config.yaml`) |
|
||
| 训练基模 | `/mnt/wangsenhao/verl_zk/Qwen3-4B-Instruct-2507` |
|
||
| 工作目录 | `/mnt/wangsenhao/autoresearch-zk` |
|
||
| 历史记录目录 | `/mnt/xiaoai-zk-model-train-tj5/workflow5/` |
|
||
| 需求集合位置 | `https://git.n.xiaomi.com/ai-service/ai-planning/-/tree/autoresearch-v1` 下 `ai-planning/data/specific_test_set/` |
|
||
|
||
## 核心原则
|
||
|
||
1. **评测优先**:`"开始"` 信号的第一个动作永远是评测当前模型,绝不直接训练
|
||
2. **假设驱动**:每轮必须能回答"这轮验证了什么?学到了什么?下一轮改什么?"
|
||
3. **NEVER STOP**:全程不打断用户,循环直到达标或人类主动打断
|
||
4. **从 basemodel 训练**:每轮 SFT 的 `--model_path` 必须是 basemodel,禁止从上轮 ckpt 继续训
|
||
|
||
## 达标条件
|
||
|
||
- **需求集合** ≥ 95%(最高优先级)
|
||
- **大盘集(车载)** 降幅 ≤ 0.3%
|
||
- **specific test** 降幅 ≤ 1%
|
||
|
||
## 主流程
|
||
|
||
读取 `references/program.md` 获取完整的 Step 0-7 迭代循环规范。在任何操作前必须读取该文件。
|
||
|
||
每个 step 的执行模板(**强制**,配合上文「Pipeline UI 同步约定」R1):
|
||
|
||
```text
|
||
1. echo '{"step":"<key>","status":"running","ts":"..."}' >> $SESSION_OUTPUT/program-state.jsonl
|
||
2. (执行该 step 的实际操作 / 调用工具 / 等结果)
|
||
3. 成功: echo '{"step":"<key>","status":"complete","ts":"..."}' >> ...
|
||
失败: echo '{"step":"<key>","status":"failed","error":"...","ts":"..."}' >> ...
|
||
```
|
||
|
||
step key 跟 Step 编号映射:
|
||
|
||
| Step | step key | 说明 |
|
||
|------|----------|------|
|
||
| Step 0 | `cml` | CML 评测当前模型 |
|
||
| Step 0 (附带) | `gold-drift` | Gold drift 检查 |
|
||
| Step 1 | `dist-analysis` | 分层结果分析 |
|
||
| Step 2 | `report` | 问题分析 & 报告 |
|
||
| Step 3 | `hypothesis` | 形成假设(写 iteration_log) |
|
||
| Step 4 | `augment` | 数据增强 / 生成 |
|
||
| Step (干预后) | `verify` | 修改返回验证 |
|
||
| Step 5 | `sft` | SFT 训练 |
|
||
| Step 6 | `log` | 记录迭代日志 |
|
||
| 循环 | `next-round` | 回 Step 0 评测新 ckpt |
|
||
|
||
```
|
||
LOOP:
|
||
Step 0: CML 评测(当前模型)+ Gold drift 检查
|
||
Step 1: 分层结果分析(需求集合 → 大盘车载 → specific test)
|
||
Step 2: 问题分析 & 报告(根因归类 / 跨轮 diff / 天花板诊断)
|
||
Step 3: 形成假设(写入 iteration_log.jsonl)
|
||
Step 4: 数据生成(仅 data 归因时做)
|
||
Step 5: SFT 训练(submit_sft_via_cml.sh)
|
||
Step 6: 记录结果(iteration_log.jsonl / error_registry.jsonl)
|
||
→ 回 Step 0
|
||
```
|
||
|
||
## 文件结构
|
||
|
||
```
|
||
references/
|
||
program.md # 完整迭代循环规范(必读,包含所有 Step 的详细说明)
|
||
knowledge/
|
||
navigation_routing_rules.md # 地图导航 Agent/CT 分流规则
|
||
travel_routing_rules.md # 旅游 Agent/CT 分流规则
|
||
multi_command_rules.md # 多指令 vs ComplexTask 分流规则
|
||
multiturn_continuity_rules.md # 多轮对话 CT 继承规则
|
||
|
||
scripts/
|
||
prepare_and_train_sft.py # 数据组装 + SFT 训练脚本
|
||
|
||
assets/
|
||
config.yaml # 评估阈值 + CML workflow 配置
|
||
```
|
||
|
||
## 何时读取各文件
|
||
|
||
| 操作 | 读取 |
|
||
|---|---|
|
||
| 启动迭代前 | `references/program.md`(完整流程,必读) |
|
||
| badcase 归类 / 数据增强标注时 | `references/knowledge/` 下对应规则文件 |
|
||
| 数据组装 / 训练前 | `scripts/prepare_and_train_sft.py`(了解脚本参数) |
|
||
| 评测阈值 / workflow 版本 | `assets/config.yaml` |
|
||
|
||
## Human-in-the-Loop 信号(需暂停问人)
|
||
|
||
共 7 类迭代级信号 + 10 类训练集调整信号(T1-T10),详见 `references/program.md` 的"Human-in-the-Loop 时机"章节。
|
||
|
||
**最常触发的**:
|
||
- Gold drift ≥ 10 条(#1)
|
||
- 要批改旧标签 > 50 条(#3 / T1)
|
||
- 跨子集净退步(#4)
|
||
- 连续 3 轮目标子集净提升 ≤ 0.5pp(#5)
|
||
|
||
## CML 配置(快速查阅)
|
||
|
||
```yaml
|
||
# ~/.config/cloudml/config.yaml
|
||
default_config_context: cloudml5-config
|
||
xiaomi_cloudml:
|
||
cloudml5-config:
|
||
xiaomi_auth_type: key
|
||
xiaomi_cloudml_endpoint: https://cnbj6-cloudml5.api.xiaomi.net
|
||
xiaomi_cloudml_workspace_id: 10065
|
||
```
|
||
|
||
## 结果文件
|
||
|
||
| 文件 | 用途 |
|
||
|---|---|
|
||
| `results/iteration_log.jsonl` | 每轮假设/干预/判定完整记录 |
|
||
| `results/error_registry.jsonl` | 跨轮错误追踪(case_hash → 出错轮次) |
|
||
| `results/workflow<runDic>.md` | 每轮回归分析报告 |
|
||
| `results/augment_raw/augment_<runDic>_raw.jsonl` | GPT-5.4 原始生成产物 |
|
||
| `ai-planning/data/train_set/zk_intent/augment_<runDic>.jsonl` | 清洗后的增量训练数据 |
|
||
| `results/data_clean_<runDic>/` | 旧数据清洗存档(必须在覆盖原文件前写入) |
|
||
| `results/gold_drift/drift_<runDic>.json` | Gold drift 检测结果 |
|
||
| `results/label_rules.md` | 已确立的标签规则集(R1~RN) |
|