Files
Video-Tree-TRM5/research-wiki/designs/2026-07-14-action-recognition-training-design.md
T
iomgaa dec7346da3 feat(harness): add Action Recognition training experiment
- PerCategoryPoolStrategy: filter test pool by task_types
- RunConfig: add run_holdout_eval toggle (default true)
- load_config: fix YAML task_types list-to-tuple conversion
- Runner: conditionally skip _holdout_four_way when disabled
- CLI: add --no-run-holdout-eval flag
- New config/train_action_recognition.yaml (3 epochs, per_category)
- New scripts/train_action_recognition.sh (baseline + seed + train)
2026-07-14 00:58:54 -04:00

7.6 KiB
Raw Blame History

id, title, type, created, status
id title type created status
action-recognition-training Action Recognition 单题型首次训练实验设计 design 2026-07-14 approved

Action Recognition 单题型首次训练实验设计

1. 目标

用 Action Recognition 单题型验证训练管线端到端可用性。选择此题型因其:

  • Video-MME 准确率 65.1%(倒数第三),提升空间大
  • 属于 RETRIEVAL family(权重最高 0.30
  • v2-360 有 30 道生成题可用于 train/val

2. 数据划分

来源 数量 用途
train (diagnosis) generated-v2-360 20 题 错误归因 + 进化
val (validation) generated-v2-360 10 题 CE-Gate 验证 + best argmax
test Video-MME benchmark 63 题 训练结束后终评(epoch 内跳过四向 held-out

切分方式:PerCategoryPoolStrategytrain_ratio=0.667,按 correctness 分层。

3. 前置步骤

步骤 1: baseline infer
  main.py --mode infer \
    --questions generated-v2-360 \
    --task-types "Action Recognition" \
    --run-id v2ar_baseline
  → workspaces/default/harness.db 新增 30 题 predictions

步骤 2: create seed
  2a. extract_run_db(
        src_db="workspaces/default/harness.db",
        dst_db="/tmp/v2ar_baseline.db",
        run_id="infer_v2ar_baseline")
  2b. init_seed(
        store_dir=Path("store"),
        name="v2ar-baseline",
        skills_dir=Path("store/skills/v1"),
        prompts_dir=Path("store/prompts/v1"),
        baseline_db=Path("/tmp/v2ar_baseline.db"),
        baseline_run_id="infer_v2ar_baseline",
        parent=None,
        description="v2-360 Action Recognition 30 题 baseline (skills/v1)")
  → store/seeds/v2ar-baseline/

步骤 3: fresh workspace
  main.py --mode train --fresh \
    --seed v2ar-baseline \
    --run-id train_ar_v1 \
    --config config/train_action_recognition.yaml
  → workspaces/train-action-recognition/

前提: workspaces/default/ 已存在(含 harness.db),步骤 1 复用该 workspace。

4. 训练配置

参数 理由
workspace_dir workspaces/train-action-recognition 独立 workspace
mode train 训练模式
run_id train_ar_v1 显式命名,observation 可追溯
questions generated-v2-360 v2-360 题目集
task_types ["Action Recognition"] 单题型
pool_split_mode per_category 按类切分
train_ratio 0.667 20 train / 10 val
test_questions benchmarks/Video-MME test 池来源(过滤后 63 题)
run_holdout_eval false epoch 内跳过四向评估 + shadow_gate
epochs 3 6 step + 3 轮慢更新
batch_size 10 20 题 / 2 batch per epoch
min_class_per_batch 2 最小值
concurrency 24 推理并发
max_steps 40 沿用默认
early_stop_patience 4 3 epoch 内有意义
use_slow_momentum true 验证 momentum
skill_mode auto 自动加载 skill

其余 gate 参数沿用 config/default.yaml 默认值。

5. 训练循环预期

Epoch 1-3 每轮:
  ├── build_batches: 20 题 → 2 batch
  ├── Step 0: rollout → diagnose → evolve → CE-Gate
  ├── Step 1: rollout → diagnose → evolve → CE-Gate
  └── Slow Update:
       ├── 全 val 重跑 (10 题)
       ├── probation 结算
       ├── best argmax
       ├── momentum
       ├── system/tool 慢更新
       └── 四向 held-out: 跳过 (run_holdout_eval=false)
           → 同时跳过 _pick_mixed_best 的 shadow val 评估
收尾:
  ├── _deliver_best: manifest 指向最佳版本
  └── _final_test_eval: test 池 63 题终评 (保留,仅跑 1 次)

预计 LLM 调用 ~500-600 次(去掉每 epoch 四向 held-out 后大幅减少)。

6. 代码修改

6.1 PerCategoryPoolStrategy test 池按 task_types 过滤

问题: PerCategoryPoolStrategy.build() Phase 4 加载 test 池时调用 load_benchmark(config.test_questions_dir) 会加载全部题目(如 Video-MME 900 题), 不受 config.task_types 过滤。而 train/val 在 Phase 1 已按 task_types 过滤, test 池应保持一致。

修改位置: app/harness/pools.py PerCategoryPoolStrategy.build() Phase 4

修改内容:

# Phase 4: test 池(从外部目录加载,无则空)
test: list[GeneratedQuestion] = []
if config.test_questions_dir is not None:
    from app.question_gen import load_benchmark
    test = load_benchmark(config.test_questions_dir)
    # 与 train/val 的 Phase 1 过滤保持一致
    if config.task_types is not None:
        allowed = set(config.task_types)
        test = [q for q in test if q.task_type in allowed]

边界情况:

  • config.task_types=None(全题型): 不过滤,行为不变
  • 过滤后 test 为空: 不报错(test 池可为空,_final_test_eval 会拿到空列表并跳过)
  • 过滤后 test 仅含目标题型: 本次为 63 道 Action Recognition

对 pools.json 冻结的影响: test 池过滤后的结果写入 pools.json, resume 时直接加载无需重新过滤。fresh workspace 每次从头构建。

测试: 新增单测验证 test_questions_dir 混合题型时过滤正确。

6.2 RunConfig 新增 run_holdout_eval

修改位置: app/harness/config.py RunConfig 字段区

run_holdout_eval: bool = True

YAML 暴露: 实验 YAML 中配置(科研实验参数归 YAML)。

CLI 覆盖: main.py 新增 --no-run-holdout-eval 标志,符合 CLAUDE.md §4.5 "CLI 仅用于单次临时覆盖"。

Runner 修改: app/harness/runner.py _slow_update_cycle Phase 9

# Phase 9: epoch_report(保留)+ 四向 held-out(可选)
write_epoch_report(...)
if self._config.run_holdout_eval:
    await self._holdout_four_way(...)

副作用说明: run_holdout_eval=false 同时跳过 _pick_mixed_best 的 shadow val 评估(best_mixed 版本选择)。首次试跑只看 best_hard shadow/mixed 指标不需要。

不影响: _final_test_eval 不受此开关控制,训练结束后仍跑一次终评。

测试: 新增 runner 单测验证 run_holdout_eval=false 时跳过 _holdout_four_way

7. 观测产出

产出 位置 内容
step 报告 analyses/step_reports/ 每步 gate 决策(accept/reject/skip
epoch 报告 analyses/epoch_reports/ 慢更新结果、best 变化
dual_metric harness.db dual_metric 表 val 准确率变化
skill 版本链 skills/v1→v2→... 可 diff 查看改动
checkpoint checkpoint.json 断点续训支持
终评 analyses/final_test_eval.json test 63 题最终准确率

8. 非功能性需求

维度 必答问题 设计
持久化 何时落盘?崩溃丢多少?覆盖还是追加? predictions 逐题 INSERT 即时落库(追加);checkpoint 每 step 结束后原子写入(覆盖);崩溃最多丢当前 step 的推理结果,resume 从上一 step 重跑
幂等性 重复执行安全吗? 同 seed + 同配置 + fresh → 确定性结果(RNG seed 固定);predictions INSERT OR IGNORE 防重复
断点续跑 中断后如何恢复? --resume 读 checkpoint.json 的 epoch/step_completed/phase,从断点下一 step 继续;epoch_done 阶段恢复到下一 epoch 开头
原子性 部分写入会损坏数据吗? checkpoint.json 整文件写入(非追加);predictions 逐条 commit 无事务风险;skills 版本目录先 copytree 再改 manifest 指针

9. 新增文件

  • config/train_action_recognition.yaml — 实验配置
  • scripts/train_action_recognition.sh — 自包含实验脚本(写死参数,零参数复现)