From 5fdcd9b5aa99be36c7478662f5672e83ad12b12d Mon Sep 17 00:00:00 2001 From: iomgaa Date: Thu, 16 Jul 2026 07:33:16 -0400 Subject: [PATCH] feat: add Video-MME 900 training entry (config + self-contained script) --- config/train_videomme.yaml | 67 +++++++++++++++++++++++++++++ scripts/train_videomme.sh | 88 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 config/train_videomme.yaml create mode 100755 scripts/train_videomme.sh diff --git a/config/train_videomme.yaml b/config/train_videomme.yaml new file mode 100644 index 0000000..83380a4 --- /dev/null +++ b/config/train_videomme.yaml @@ -0,0 +1,67 @@ +# config/train_videomme.yaml +# Video-MME 900 题自进化训练 —— 消费 video-split 冻结切分(global 三池) +# +# 数据来源: workspaces/video-split/pools.json(tier 感知 diag/val + val 功效修复) +# 经 adhoc-baseline seed 携带进 workspace(WP2 接线)。 +# 训练前置: .env REDIS_CACHE_TTL 须为正整数(WP4 fail-loud);见 +# research-wiki/reviews/2026-07-16-preflight-final-review.md runbook。 + +harness: + workspace_dir: "workspaces/train-videomme" + store_dir: store + mode: train + run_id: train_videomme_v1 + concurrency: 24 + max_steps: 40 + skill_mode: auto + n_samples: 0 + questions: "benchmarks/Video-MME" # gate 指纹依赖加载全 900 题 + skills_version: v1 + prompts_version: v1 + epochs: 3 + # CE-Gate 参数(沿用 default.yaml) + gate_e_confirm: 20.0 + gate_e_provisional: 3.0 + gate_w_net_min: 2 + gate_delta_min: 0.02 + gate_lambda_dir: -0.642 + gate_e_rollback: 10.0 + gate_block: 8 + gate_n_max: 40 + gate_p_low: 0.05 + gate_p_high: 0.95 + gate_probe_quota: 0.2 + gate_gamma_decay: 0.9 + gate_cooldown_steps: 2 + gate_guard_err: 0.10 + # 进化参数 + edit_budget_start: 5 + edit_budget_end: 2 + skill_update_mode: patch + appendix_consolidate_threshold: 6 + # 池配置 —— global 冻结切分(diag/val/test 尺寸由 pools.json 冻结,以下采样旋钮加载时忽略) + pool_split_mode: global + diag_size: 210 + diag_correct_ratio: 0.5 + val_size: 90 + val_correct_ratio: 0.5 + test_size: 600 + test_questions: "benchmarks/Video-MME" + # 可训练性预检(WP3):val 单元 < eval_min_per_class 或 非test单元 < trainable_min_units 的题型剔除 + eval_min_per_class: 2 + trainable_min_units: 8 + # mini-batch + batch_size: 10 + min_class_per_batch: 2 + batch_correct_ratio: 0.5 + momentum_samples: 20 + early_stop_patience: 2 # epoch 粒度(WP3):连续 2 epoch 无 best 刷新即停 + use_slow_momentum: true + run_holdout_eval: true # 逐 epoch test 四向评估(WP3 去重版:baseline 推导 + 版本备忘录) + # 全 12 题型(不指定 task_types 子集,避免 I-4 语义偏差;微型类由预检自动剔除) + +embed: + backend: "local" + model_name: "BAAI/bge-base-zh-v1.5" + embed_dim: 768 + device: "cuda" diff --git a/scripts/train_videomme.sh b/scripts/train_videomme.sh new file mode 100755 index 0000000..4e0cd31 --- /dev/null +++ b/scripts/train_videomme.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +# ============================================================================ +# Video-MME 900 自进化训练 —— 消费 video-split 冻结切分(capstone 训练) +# ---------------------------------------------------------------------------- +# 自包含实验记录:写死全部参数,零参可复现(GPU 卡号除外)。 +# +# Phase 0: 建 adhoc-baseline seed(extract infer_adhoc 去重 baseline.db + +# 携带 video-split 冻结 pools.json / manifest;已存在则跳过) +# Phase 1: train --fresh --seed adhoc-baseline(3 epochs,global 冻结切分) +# +# 用法(长时训练,建议 tmux 便于 attach 看实时进度): +# tmux new-session -d -s train_videomme "CUDA_VISIBLE_DEVICES=0 bash scripts/train_videomme.sh 2>&1 | tee logs/train_videomme.log" +# 或直接: CUDA_VISIBLE_DEVICES=0 bash scripts/train_videomme.sh +# +# 日志三重保险即时输出(绝不缓存): PYTHONUNBUFFERED=1(环境级)+ python -u(命令级) +# + loguru 走 stderr 同步写。tee 落盘不影响实时性。 +# +# 前置(务必先做,见 research-wiki/reviews/2026-07-16-preflight-final-review.md): +# 1. .env REDIS_CACHE_TTL 为正整数(0 会被 WP4 fail-loud 拒绝启动) +# 2. workspaces/video-split/pools.json 已冻结(build_video_split.sh 产出) +# 3. workspaces/default/harness.db 含 infer_adhoc 基线预测 +# ============================================================================ + +set -euo pipefail + +cd "$(dirname "$0")/.." + +export CUDA_VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES:-0}" +export HF_HUB_OFFLINE=1 +export TRANSFORMERS_OFFLINE=1 +export PYTHONUNBUFFERED=1 + +set -a +source .env +set +a + +PYTHON="$(conda run -n Video-Tree-TRM which python)" + +SEED_NAME="adhoc-baseline" +SPLIT_DIR="workspaces/video-split" +BASELINE_DB="workspaces/default/harness.db" + +# ── Phase 0: 建 seed(携带冻结 pools.json)── +if [[ ! -d "store/seeds/${SEED_NAME}" ]]; then + echo "=== Phase 0: 建 seed ${SEED_NAME}(携带 video-split 冻结切分)===" + "${PYTHON}" -u -c " +from pathlib import Path +import tempfile +from app.harness.store import extract_run_db, init_seed + +split_dir = Path('${SPLIT_DIR}') +pools = split_dir / 'pools.json' +manifest = split_dir / 'split_manifest.json' +assert pools.exists(), f'冻结切分不存在: {pools}(先跑 build_video_split.sh)' + +tmp = Path(tempfile.mkdtemp()) / 'baseline.db' +# canonical 每 question_id 取首行(902→900),对齐冻结切分口径 +extract_run_db(Path('${BASELINE_DB}'), tmp, 'infer_adhoc', dedupe_per_question=True) +init_seed( + store_dir=Path('store'), + name='${SEED_NAME}', + skills_dir=Path('store/skills/v1'), + prompts_dir=Path('store/prompts/v1'), + baseline_db=tmp, + baseline_run_id='infer_adhoc', + parent=None, + description='Video-MME adhoc baseline + video-split 冻结三池(tier 感知 val_ratio=0.4)', + pools_json=pools, + split_manifest=manifest, +) +tmp.unlink() +print('Seed created: store/seeds/${SEED_NAME}/') +" +else + echo "=== Phase 0: seed ${SEED_NAME} 已存在,跳过 ===" +fi + +# ── Phase 1: Train ── +echo "=== Phase 1: Train (3 epochs, Video-MME 900 global 冻结切分) ===" +"${PYTHON}" -u main.py \ + --config config/train_videomme.yaml \ + --fresh \ + --seed "${SEED_NAME}" + +echo "=== 训练完成 ===" +echo "结果查看:" +echo " cat workspaces/train-videomme/analyses/final_test_eval.json" +echo " sqlite3 workspaces/train-videomme/harness.db 'SELECT * FROM dual_metric'"