Download train.md from tchbcb/qwenjev: direct link, hf CLI and curl.
- Browser
- Download file 30.8 kB
-
https://huggingface.co/tchbcb/qwenjev/resolve/main/train.md
- Command line
-
hf download hf://tchbcb/qwenjev/train.md
-
curl -L -o train.md https://huggingface.co/tchbcb/qwenjev/resolve/main/train.md
QwenJev — 用 Qwen3.5-9B 多模态改造 NanoJev 的 ARC-AGI-3 双系统智能体
本文档是整个项目的构造蓝图:背景 → 架构 → 数据 → 训练 → 智能体接入 → Kaggle 部署 → 评测 → 路线图。 按顺序读完即可独立复现整个系统。README 按要求留空,所有内容都在本文档中。 v0.2.0 架构决策:视觉塔必保留在 System-1 每步推理路径上——隐藏关全是陌生机制, 只看 hex 文本串没法玩游戏;本仓库的 System-1 骨干直接是多模态模型,每步都"看"当前帧。
1. 项目定位
1.1 要解决的问题
ARC Prize 2026(ARC-AGI-3)要求智能体在从未见过的交互式游戏环境中探索、获取目标、构建世界模型。评分采用 RHAE(Relative Human Action Efficiency):完成度 × 效率(步数取平方惩罚),意味着瞎探索的代价极高。
原始 NanoJev(TianyuCodings/NanoJev,0.6B)是一个极合适的 System-1 决策内核:states + questions 进,完整概率分布出,零输出 token 解码。但它有两个与本赛不匹配的短板:
- 没有视觉塔——骨干是纯文本的 Qwen3-0.6B,只能吃文本化的网格;
- 没有游戏级的探索/反思机制——它是一个"打分器",不是完整智能体。
1.2 QwenJev 的改造思路
| 短板 | 改造手段 | 落点 |
|---|---|---|
| 无视觉塔 | 视觉塔直接保留在 System-1 推理路径上:骨干改为多模态模型(hf 后端 = Qwen3-VL 系列,预训练视觉塔原样保留;tiny 后端 = 自带微型视觉塔),叶子升级为 [帧图像, state, instruction, candidate],每步都看当前帧 |
qwenjev/vision.py + qwenjev/system1.py |
| 小模型感知不如 9B | Qwen3.5-9B 做冻结教师,吃同一帧、过自己的视觉塔,把逐层隐状态蒸馏对齐给学生(stage A) | train/distill_alignment.py |
| 缺少探索机制 | 9B 作为 System-2 主控:感知局面、提出候选动作假设、失败后写记忆笔记;由调度器稀有地唤醒 | qwenjev/system2.py |
| 单步决策慢/贵 | NanoJev 式 System-1:单次前向输出候选动作分布,每步都跑(含视觉前向) | qwenjev/system1.py |
| 接口封闭 | 完整对接官方 ARC-AGI-3-Agents 开源框架,实现 Agent 两个方法即可提交比赛 |
agent/qwenjev_agent.py |
| 本地无 GPU/无游戏 | 内置 mock 推箱游戏(多关卡、种子确定)+ tiny 微型 VLM(~1M 参数,纯 CPU),全管线零下载跑通 | data/mock_env.py |
一句话:视觉塔每步都在环上(System-1 骨干原生多模态);9B 出眼光(教师蒸馏 + System-2 稀有唤醒);tiny 后端让全链路在笔记本 CPU 上跑通。
1.3 与 NanoJev 原作的关系
- 忠实保留其输入契约:每个问题 = 一个 state + 一组候选;每个候选编码为
[帧图像, state, instruction, candidate]的多模态叶子(原作为纯文本[state, instruction, candidate]);候选路径重复 state;问题之间独立(前向中无跨问题注意力)。 - 忠实保留三种原语:
Choice(2–255 候选,set-attention + softmax)、Boolean(sigmoid p_true)、Score(2–10 有序等级,期望值读出)。 - 沿用其训练配方:complete-question 交叉熵,backbone lr
1e-5、decision-head lr1e-4。 - 差异点:① state 序列化改为版本化规范串(原作审计文档承认
str()序列化非规范,属遗留问题);② 叶子多模态化——视觉塔每步在环;③ 增加 ACTION6(x,y) 的候选离散化;④ 外层接 ARC-AGI-3 环境与双系统调度。
2. 总体架构
┌────────────────────────────────────────────┐
│ ARC-AGI-3-Agents 官方框架循环 │
│ main.py → Swarm → Agent.choose_action() │
└───────────────┬────────────────────────────┘
│ frames / FrameData
▼
┌────────────────────────────────────────────┐
│ agent/qwenjev_agent.py │
│ is_done(): state is WIN │
│ choose_action(): 严格解析 + 安全回退 │
└───────────────┬────────────────────────────┘
▼
┌────────────────────────────────────────────┐
│ qwenjev/hybrid.py │
│ 调度器: novelty / reward / stall 触发 │
│ 动作-效果记忆 + 时间预算管理 │
└──────┬───────────────────────┬─────────────┘
唤醒(稀有) │ │ 每步(便宜)
▼ ▼
┌────────────────────────┐ ┌────────────────────────────────┐
│ System-2 主控 (慢) │ │ System-1 决策模型 (快) │
│ Qwen3.5-9B 多模态 │ │ 多模态骨干 + 决策头 │
│ · 感知局面 summarize │ │ · 视觉塔: 每步编码当前帧 ★必保留 │
│ · 假设机制 hypothesize │ │ · Choice 头: 候选动作打分 │
│ · 提议候选 propose │ │ (set-attn + softmax) │
│ · 失败反思 reflect │──▶ · Boolean 头: 动作-效果判真 │
└────────────────────────┘ │ · Score 头: 局面价值分级 │
▲ 训练期教师 └────────────────────────────────┘
│ 同一帧过双方视觉塔 叶子 = [帧图像, state, instruction,
└── 蒸馏对齐 (stage A) ── candidate],同题共享帧
qwenjev/vision.py 负责网格→图像/张量、多模态叶子、TinyVLM
数据流要点:
state_codec.encode_observation()把每步的帧数组编码为:规范 state 串 + 差分网格(*标记变化格,供"上一步干了什么"这一最廉价的学习信号)+ 帧哈希(新颖性检测)。candidates.build_candidates()生成候选:简单动作(ACTION1–5、ACTION7=undo)+ ACTION6 的锚点离散化(变化格 > 稀有格 > 8×8 粗格网,上限 255)。- 当前帧随每步决策进入 System-1 视觉塔(
hybrid.decide()把grids[0]传给s1.choose())——这是 v0.2.0 的硬性架构约束,不许回退到纯文本。 - System-2 提议的候选被稳定置顶(不删除其他候选),最终仍由 System-1 打分决定——9B 可以错,打分器说了算。
- RESET 永远不进候选列表,只由生命周期守卫(NOT_PLAYED / GAME_OVER / 超时)触发,防止自杀式重启。
3. 核心模块详解
3.1 视觉塔 qwenjev/vision.py(v0.2.0 新增,架构核心)
为什么必须保留视觉塔:ARC-AGI-3 的智能体只能通过帧观察世界;隐藏评测关的机制全部陌生,实体形状、邻接、运动这些线索在 hex 文本串里大量丢失。System-2 每局最多唤醒 40 次,不能指望 9B 替 System-1 看路——所以视觉塔必须长在每步都跑的 System-1 上。
两种可互换后端(同一接口):
| 后端 | 骨干 | 用途 |
|---|---|---|
"hf" |
AutoModelForImageTextToText 加载的 Qwen3-VL 系列多模态权重(默认 Qwen/Qwen3-VL-2B-Instruct) |
正式训练/提交;预训练视觉塔原样保留,可选 freeze_vision_tower |
"tiny" |
TinyVLM:patch-embed 微型 ViT 塔(64 视觉 token)+ byte 级微型因果 LM(~1.1M 参数) |
本地跑通/CI/单测;零下载、纯 CPU、毫秒级 |
多模态叶子 MultiModalLeaf = [图像, state 文本, instruction, candidate]:同题候选共享同一帧,encode_question() 一次构造全部叶子。关键实现细节:注意力掩码用 additive float mask(-1e9)而不是 bool 掩码——bool 掩码与 causal 组合会在 padding 行产生全 -inf → softmax NaN(开发中实际踩过并修复,单测 test_tinyvlm_all_finite_with_padding 永久看守)。
3.2 状态编码 qwenjev/state_codec.py
- 网格 → 文本:每格一个字符,0–15 → hex(
0123456789abcdef),64×64 最多 4KB,远比视觉 token 便宜且无损。 - 差分网格:与上一帧逐格比较,变化格写
*。注意实现教训:hex 字母可以大写标记,但0-9是数字无法大写——所以用专用标记符(单测覆盖了这个坑)。 - 规范 state 串:
qwenjev-state-v1|h=.. w=.. l=.. s=..\n<网格>。版本号置顶 + meta 键排序,保证同一局面永远产出同一字符串(checkpoint 可复现的前提)。 - 网格 → 图像:
grid_to_image()用 16 色稳定调色板渲染。v0.2.0 起不只是 System-2 用:System-1 视觉塔每步也吃这张图(vision.py转张量/PIL)。
3.3 候选生成 qwenjev/candidates.py
ACTION6(x,y) 是唯一带坐标的动作,必须离散化才能进 Choice 头。锚点优先级:
- 变化格(上一帧的
*位置)——游戏机制大概率藏在这里; - 稀有格(非零值按局部稀有度排序 top-24)——目标物/关键机关往往颜色稀缺;
- 8×8 粗格网兜底(保证全图覆盖)。
上限 255 候选(TypeSafe Choice 契约上限),顺序稳定,避免候选索引漂移悄悄改变叶子输入。
3.4 System-1 qwenjev/system1.py
encode_question(state, candidates, instruction, grid)→ N 个多模态叶子(每候选一个,state 重复,当前帧图像共享);forward_choice(leaves)→ 一次 backbone 前向(含视觉塔):叶子向量 → 投影 → set-attention(同题候选间)→ softmax → 概率列表;choose(..., grid)→ 贪心或按分布采样,返回Decision(probs, candidates, chosen, index);forward_boolean/forward_score及其可训练孪生forward_boolean_logits/forward_score_logits(v0.2.0 修复:旧实现返回 detach 张量,梯度根本流不进模型);save()/load_heads():tiny 后端打包 backbone + 全部头;hf 后端只存头(权重留在 HF 权重目录);eval()/train_mode():决策头 dropout=0,保证加载后推理确定。
3.5 System-2 qwenjev/system2.py
- 两种后端:
mode="openai"(vLLM 的 OpenAI 兼容端点,首选)或mode="transformers"(进程内加载,重); perceive(obs, grids, memory)→ 结构化PerceptionReport:局面摘要、实体清单、≤3 条机制假设、3–8 个建议动作;输入含 hex 网格文本 + 渲染 PNG(双通道喂视觉塔)+ 记忆笔记;reflect(history)→ GAME_OVER/停滞后的持久记忆{learned, avoid, next_try},跨 episode 保留;bias_candidates()把 9B 的建议动作稳定置顶(保留全部候选)。
3.6 调度器 qwenjev/hybrid.py
System-2 唤醒条件(满足其一,且调用数 < system2_max_calls_per_game):
| 条件 | 含义 |
|---|---|
| 新帧哈希 | 局面没见过,需要 9B 看一眼 |
levels_completed 增加 |
进新关卡,机制可能变 |
| 连续 12 步无变化 | System-1 卡死,需要外部视角 |
同时管理:每局时间预算(默认 900s,官方文档明确超时会直接 fail 该次运行)、动作数上限、动作-效果记忆(哪个动作改变多少格)、每局反思笔记。
任何一层失败都不能杀死运行:9B 端点挂了 → 跳过;System-1 权重缺失 → 启发式策略;输出不合法 → 正则清洗 + 安全回退(官方文档警告:一个畸形输出就会以 ValueError 终结当前游戏)。
4. 数据管线
4.1 来源:25 个公开游戏自采(已确认可用,2026-09-23 实测)
- 游戏源码从 arcade API 自动获取:
arc-agi包 NORMAL 模式make()会把游戏源码(单游戏约 120KB)缓存到environment_files/<game_id>/<version>/,之后永久离线(OFFLINE 模式约 2000 FPS、无限实例);匿名 key 自动下发,无需 Kaggle 账号、无需接受比赛规则。一键预缓存:python ops/fetch_games.py(25 游戏约 65 秒); - kagglehub 比赛下载(
kagglehub.competition_download('arc-prize-2026-arc-agi-3'))需要 KGAT token + 官网接受规则,且与本地游戏引擎是同一套(arc-agi包本地托管同引擎)——本仓评测链路已不依赖它; - 游戏清单(与 arcprize.org/tasks 一致,
ops/run_eval.py --list-games可从 API 拉实时列表):ar25 bp35 cd82 cn04 dc22 ft09 g50t ka59 lf52 lp85 ls20 m0r0 r11l re86 s5i5 sb26 sc25 sk48 sp80 su15 tn36 tr87 tu93 vc33 wa30; - 评测是另外 110 个从未公开的隐藏游戏(55 个 Public LB + 55 个 Private LB),所以数据管线的一切设计都服务于"可泛化的探索先验",而非背题。
4.2 采集 data/collect_selfplay.py
- ε-greedy(默认 ε=0.25)包住当前 HybridAgent 策略;
- 每步记录:动作、坐标、前后帧、
levels_completed变化、可用动作集、帧哈希、规范 state; - 输出 JSONL 分片
data/traces/<game>/ep*.jsonl+summary.json; - 游戏源双轨:
game_id以mock开头 → 内置推箱游戏(零依赖);否则走arc-agi离线引擎(需安装包 + 游戏文件); - 批量采集时 System-2 默认关闭(吞吐优先),可选开启给少量轨迹加 9B 注释。
4.3 内置 mock 游戏 data/mock_env.py(v0.2.0 新增)
多关卡推箱游戏("sokoban-lite"),实现官方环境契约的子集:reset()/step()/observe()、FrameData 兼容字段、RESET/ACTION1-7 全动作、≤64×64 网格值 0–15、种子确定(crc32)可复现。机制刻意稀疏:推箱进目标才涨关卡、超预算 GAME_OVER——正好复刻隐藏关的稀疏奖励探索难度。step_env() 适配器统一 mock(按名调用)与官方引擎(GameAction 枚举)。
4.4 构造训练样本 data/build_dataset.py
| 问题族 | 问题模板 | 标签来源 |
|---|---|---|
| Choice(主任务) | "哪个候选动作最可能取得进展?" + 全部候选 | 即时结果分级:levels_completed 增加=+2;帧变化未丢关卡=+1;无变化=0,取最优动作为 one-hot |
| Boolean(效果预训练) | "ACTION k 会改变画面吗?" | 前后帧哈希差 |
| Score(价值塑形) | "当前局面希望多大?" 2–10 级 | 关卡进度 + 探索覆盖率的启发式 |
每个样本都携带 grid 字段(v0.2.0 起):System-1 的视觉塔训练/推理都要吃图像,样本不带帧就没法训。划分逻辑:≥5 个游戏时按游戏切分 train/val(防同游戏泄漏);单游戏冒烟时退化为按行 crc32 哈希切分(保证 train 非空——单游戏场景下按游戏切会把全部样本切进 val,开发中踩过)。
4.5 增广 data/augment.py
ARC 传统增广全部可用:转置/镜像/旋转/重着色(固定 0=背景)。ACTION6 坐标必须与网格同步变换(coord_transform()),否则标签说谎。
5. 训练方案
5.1 两阶段配方
Stage A:视觉蒸馏对齐(train/distill_alignment.py)
- 教师:冻结的多模态模型,同一帧真实过其视觉塔(hf 后端:processor 构造
pixel_values进模型前向;tiny 后端:教师 TinyVLM 同样吃图像张量)——绝不允许出现"蒸馏时没看图"的假对齐(v0.1 的占位符实现已废弃); - 学生:System-1 多模态骨干,同样图像+文本前向,取逐层隐状态池化;
- 对齐层集隐状态(默认最后 2 层),
1 − cosine损失,逐层独立投影头; - 产物:
checkpoints/qwenjev-s1/stage_a.pt(投影头 + tiny 学生权重),Stage B 自动加载。
Stage B:决策头 SFT(train/train_system1.py)
| 超参 | 值 | 出处 |
|---|---|---|
| 目标函数 | complete-question CE(整题 softmax,非逐叶子二分类) | NanoJev hard_lr1e5 |
| backbone lr | 1e-5 | 同上 |
| decision-head lr | 1e-4 | 同上 |
| epochs | 4(三族问题混合,真实网格随样本进视觉塔) | 可调 |
| LoRA | 默认关闭;hf 大骨干时建议开 r=32, α=64 |
可选 |
v0.2.0 训练修复清单(旧代码静默失效的三处):① Boolean/Score 头改用可训练 logits 孪生方法,BCE/CE 梯度真正流进模型;② Choice 批训练改用带图前向(旧行为在 torch.no_grad() 里算概率再包装,同样训不动);③ Stage A checkpoint 自动加载,蒸馏成果不白费。
5.2 显存预算(RTX Pro 6000 96GB 实测口径)
| 场景 | 占用估算 |
|---|---|
| Stage A:9B 教师 4bit + Qwen3-VL-2B 学生(含双方视觉塔前向) | ~12–16 GB |
Stage A:9B 教师 BF16(teacher_4bit: false) |
~28–32 GB |
| Stage B:Qwen3-VL-2B 全参数训练 | ~20–26 GB;LoRA 减半以下 |
| 推理:System-1(2B)+ System-2(9B BF16)常驻 | ~26 GB,96GB 富余 |
消费级 24GB 卡(4090/3090)建议:教师 4bit + 学生 LoRA;tiny 后端则任意机器(含无 GPU 笔记本,~1.1M 参数 fp32 ≈ 5MB)都能跑。
5.3 下载权重
python scripts/download_weights.py # Qwen3-0.6B + Qwen3.5-9B + NanoJev 参考
6. 智能体接入(官方开源框架)
6.1 安装到 ARC-AGI-3-Agents
git clone https://github.com/arcprize/ARC-AGI-3-Agents.git
cd ARC-AGI-3-Agents
# 1) 拷贝本仓库的 agent/qwenjev_agent.py 到 agents/
# 2) 保证 qwenjev 包可导入(repo 根目录放本仓库,或 pip install -e)
# 3) 注册:
# agents/__init__.py 中加入
# from .qwenjev_agent import QwenJevAgent
# AVAILABLE_AGENTS["qwenjevagent"] = QwenJevAgent
uv run main.py --agent=qwenjevagent --game=ls20 # 单游戏试跑
uv run main.py --agent=qwenjevagent # 全部游戏
6.2 框架接口速查(v0.9.3)
- 基类
Agent,必须实现is_done(frames, latest_frame)与choose_action(frames, latest_frame) -> GameAction; FrameData关键字段:levels_completed/win_levels(v0.9.3 由score/win_score改名)、available_actions(v0.9.2+)、state;GameAction:RESET、ACTION1–7;action.is_simple()/action.is_complex();复杂动作action.set_data({"x":..,"y":..});- 网格 ≤64×64,值 0–15,(0,0) 左上,(x,y) 顺序;
- 游戏状态:
NOT_PLAYED / NOT_FINISHED / WIN / GAME_OVER。
7. Kaggle 部署(比赛提交)
7.1 硬件与限制
| 项 | 值 |
|---|---|
| 专属加速器 | RTX Pro 6000(g4-standard-48:1×96GB 显存、48 vCPU、180GB 内存) |
| 运行上限 | CPU/GPU Notebook 均 ≤ 9 小时 |
| 网络 | 禁网(权重/依赖全部走 Kaggle Dataset) |
| 配额 | RTX 并发 1/人,高峰排队可达数小时——只在完整方案上烧 Commit |
7.2 打包步骤(scripts/package_kaggle.py)
python scripts/package_kaggle.py --username <你的Kaggle用户名> --accelerator rtx6000
cd kaggle_kernel && kaggle kernels push -p .
生成的 notebook 三个关键单元格:
- 从比赛 Data 包的
arc_agi_3_wheels/离线安装 arc-agi(禁网解法一); - 挂载权重 Dataset(
/kaggle/input/qwenjev-weights/...,公开预训练权重合规); - 实例化
QwenJevAgent,接入官方 sample-submission 驱动循环,工具包自动产出submission.parquet。
7.3 九小时时间预算(务必先算再跑)
- 隐藏集 110 局;平均每局预算 ≈ 4.9 分钟;
- System-1 每步毫秒级,主导耗时的是 System-2:单次调用按 3–5s 计,每局
system2_max_calls_per_game=40→ 9B 总开销 ≈ 2–3.3 分钟/局,留有余量但不富裕; - 调参顺序:先压
system2_max_calls_per_game,再压stall_patience;game_time_limit_s宁低勿高(超时=整局报废)。
8. 评测与迭代
8.1 一键评测(v0.4.2 起:ops/run_eval.py)
pip install arc-agi # 官方本地引擎(PyPI,纯 Python)
pip install -U "torchao>0.16" # v0.4.3 实测坑:旧版 torchao 会令 hf 加载失败(见下)
python ops/run_eval.py --download-only # 一次性缓存 25 公开游戏(约 3MB,匿名 key)
python ops/run_eval.py --games all25 # 全量评测:GPU→hf 后端自动拉 HF 检查点并 merge LoRA;无 GPU→tiny
python ops/run_eval.py --games ls20 --max-actions 60 # 指定游戏 + 预算
python ops/run_eval.py --backend tiny --no-checkpoint --games mock --max-actions 60 # 纯 harness 冒烟
python ops/run_eval.py --checkpoint /path/to/dir --games ... # 本地检查点目录(qwenjev_s1.pt [+ hf_lora/])
- 检查点解析(默认
hf:tchbcb/qwenjev@t4_assets_v2/checkpoints):自动下载 qwenjev_s1.pt + hf_lora 分片 →parts/reassemble重组 → sha256 校验 → 后端 auto 决定 hf(fp16 基座 + LoRA merge,与训练同构)或 tiny; - 生命周期:WIN 结束本局;GAME_OVER 触发
brain.on_game_over+ 自动重置续玩(同一动作预算内公平比较,resets入报告); - 报告字段:
win / final_state / best_level / resets / actions / seconds / steps_per_s,默认写eval_report.json(--out改路径); - 增量落盘(v0.4.3):每完成一个游戏即原子重写报告(
.tmp→replace),Colab/隧道中途断连也保留已完成游戏的结果,报告meta+summary.played恒反映已落盘部分; - torchao 坑(v0.4.3 实测):transformers 5.16.1 加载 Qwen3-VL 时校验 torchao 版本,
torchao==0.10.0会令build_s1抛 "only versions above 0.16.0 are supported",run_eval 静默回退启发式策略继续跑完(不中断)——健康检查判据:steps_per_s > 100必是启发式,真模型推理约 1 步/秒量级(T4 实测 1.15 步/秒 @ 150 步预算);pip install -U torchao(0.18.0 验证通过)后重跑即可; --list-games从 arcade API 拉实时游戏列表(静态清单兜底)。
8.2 本地 CPU 能不能跑?(2026-09-23,2 核 / 3GB 容器实测)
| 配置 | 可行性 | 实测/推算依据 |
|---|---|---|
| tiny 后端 + v0.2.0 训练头(128 维) | ✅ 完整评测 | 25 游戏全部跑通(40 步/游戏),0.5–4 步/秒(快慢取决于 ACTION6 候选数) |
| tiny 后端 + v2 检查点 | ❌ 维度不匹配 | v2 头是 2048 维(hf 隐藏维),tiny 骨干是 128 维 |
| hf 后端(Qwen3-VL-2B fp16) | ⚠️ 需 ≥8GB 内存 | 基座权重 ~4.4GB + 三头 254MB(fp32, 63.5M 参数)+ 激活;本 3GB 容器物理不可行;bitsandbytes 4bit 仅限 CUDA,CPU 无替代 |
| hf 后端(GPU:T4 16GB) | ✅ 已验证 | fp16 基座 + merge 后 300 步 601.6s(§11.2 v2 eval) |
CPU 评测的检查点是
checkpoints/qwenjev-s1/(v0.2.0 时代 128 维 tiny 头 + backbone,load_heads向后兼容:escalate/温度表缺省跳过);其结论只用于 harness 验证与横向对比,不代表 v2 模型水平;4bit 量化在 CPU 上不可用(bitsandbytes 依赖 CUDA),若要在 CPU 跑真 2B 建议在 ≥16GB 内存机器用 fp16(
--backend hf会自动走resume_adapters(merge=True));提速方向:调小候选池(
build_candidates的 ACTION6 锚点数)或调大eval_leaf_batch。官方正式指标 RHAE = 按关卡
min(人类步数/智能体步数, 1.0)²加权平均,人类基线本地拿不到——所以evaluate_local.py的绝对分数只用于横向比较不同版本的智能体,不代表排行榜;迭代循环:改
agent/my_agent.py(或 hybrid 配置)→ 本地秒级验证 → 满意后再花 Kaggle Commit;关注三条曲线:完成率(WIN 数)、平均步数、System-2 调用次数。好方向的标志是完成率升、System-2 调用降。
8.3 v3 真游戏训练轮(2026-09-23,进行中)
背景:v2 只见过 mock 推箱,zero-shot 25 公开游戏 2 局实测 0 胜 0 关(§3 基线)→ 转真游戏训练。
采集(真数据比预想廉价得多):
- 工具:
scripts/collect_chunk.py(分块断点续采,本地沙盒前台 <9 分钟/调用友好; 非空 ep 文件即视为完成——多数游戏 ε=0.35 随机探索几十步就 GAME_OVER,早死也是有效信号); - 配置:
configs/collect_real25.yaml(25 游戏 × 8 集 × 400 步,ε=0.35,seed 13); - 实测吞吐:本地 2 核 ~9 步/秒(ar25 64×64 大网格),小网格 60+ 步/秒;远端 2 核 nohup 全量 24 游戏 × 10 集约 90 分钟;
- 本地 3GB 内存注意:
build_dataset.py已瘦身(只保留grids_before[0],丢 grids_after 与多帧, 内存降 ~70%;顺带跳过截断行)——全量 2.8GB 轨迹可在 3GB 容器构建成功。
数据:远端 37,890 步 + 本地 36,918 步 → 合并 167,635 样本 (choice 18,389 / boolean 74,338 / score 74,808 量级,train 158,290 + val 9,245),约为 v2 mock 语料 6 倍。
训练(ops/t4_real25.py,远端 nohup python3 -u -B t4_real25.py):
- 阶段 stamp 幂等(
/content/qwenjev_work_v3/done_v3/*.stamp),失败重跑自动跳过已完成阶段; - prep:HF 匿名拉 v2 hf_lora 分片重组(sha256 校验)→
stage_a_lora/起点(与 zero-shot 基线同起点,对照干净); - real_b:SFT 180 步(~38s/步,T4 ~2 小时;峰值 12.6GB/15GB);
- real_c:RLCD + 校准 → 产物自动推 HF
t4_assets_v3/checkpoints/; - 评对照:
python ops/run_eval.py --games ar25 bp35 --max-actions 150 --checkpoint hf:tchbcb/qwenjev@t4_assets_v3/checkpoints --backend hf。
判据:best_level_sum > 0(v2 基线=0)即真数据生效;仍 0 → ε 提 0.45 + System-2 教师蒸馏 + 25×16×600 重采。
9. 路线图
| 里程碑 | 内容 | 验收标准 | 状态 |
|---|---|---|---|
| M0 | 仓库骨架 + 单测 + 文档 | make test 全绿 |
✅ |
| M1 | 本地全链路跑通:mock 游戏 → 采集 → 建库 → Stage A 蒸馏 → Stage B 训练 → 评测(视觉塔全程在环) | make smoke 五环节全绿,蒸馏 loss 收敛,36 个单测通过 |
✅ |
| M2 | 换 hf 后端:Qwen3-VL-2B 学生 + 9B 教师,25 公开游戏真实采集 | Choice 标签集 ≥ 5 万题,公开关 eval 完成率显著高于随机基线 | |
| M3 | System-2 接入 + 调度调参 | 完成率升 & 9B 调用数下降 | |
| M4 | Kaggle 打包提交 | 官方 LB 出分,进入迭代循环 |
后续方向:RLCD 后训练(NanoJev 官方 roadmap 同款)、共享前缀推理提速、把 Score 头升级为学习型局面价值模型。
10. 风险与合规清单
- 泛化陷阱:隐藏 110 关机制全部陌生,过拟合 25 公开关 = 白给。每轮训练都要看"未见过游戏"上的表现(val 按游戏切分就是为此)。
- 畸形输出即死刑:官方文档明确模型回包必须严格解析为合法动作名,否则
ValueError终结当前游戏——qwenjev_agent.py已内置正则提取 + 随机合法动作回退。 - RESET 滥用:RESET 不在候选池,仅由生命周期守卫触发。
- Testing Policy:官方对评测环境禁止逆向/探测/暴力破解(详见 arcprize.org 的 Testing Policy),提交前务必通读并遵守。
- 开源义务:获奖者不开源方案会被取消资格——本仓库 MIT 协议即为此准备。
- Token 安全:HF/Kaggle token 只放
.env(已 gitignore)或环境变量;任何在聊天/截图中明文出现过的 token,用完后建议立刻轮换。 - 成本纪律:RTX 排队以小时计且配额独占,本地
make play-local/make eval先行,Kaggle Commit 只留给接近最终的版本。
11. 命令速查
make setup # 环境安装(Python 3.12+)
make test # 单测 36 个(纯 CPU,零下载)
make smoke # 一键本地跑通:mock采集→建库→蒸馏→训练→评测(无GPU可用)
make collect # 自博弈采轨迹(mock 游戏 / 25 公开游戏)
make build-data # 轨迹 → Choice/Boolean/Score 训练样本(含 grid 帧字段)
make distill # Stage A:9B 教师 → System-1 学生 视觉蒸馏对齐
make train-s1 # Stage B:决策头 SFT(NanoJev 配方,自动加载 stage A)
make eval # 本地评测(mock 游戏默认)
make push-hf # 推送本仓库到 HuggingFace(HF_TOKEN 从环境读)
python scripts/download_weights.py # 拉权重
python scripts/serve_system2.py --port 8000 # 9B 端点(transformers 兜底)
# vllm serve Qwen/Qwen3.5-9B --port 8000 # 9B 端点(首选)
python scripts/package_kaggle.py --username XXX --accelerator rtx6000
11.1 本地跑通记录(v0.2.0,2026-09)
无 GPU(4GB RAM / CPU)环境实测:make smoke 全链路通过——mock 游戏 2400 步轨迹、5267 样本(train 4927 / val 340)、Stage A 蒸馏 56 步 align_loss 0.0062→0.0012 收敛、Stage B 三头联训完成、评测 agent 完整跑 600 步决策(每步含视觉塔前向,~210ms/步)。
切换真实模型的路径:configs/train.yaml 里 system1.backend: "hf"(学生 Qwen/Qwen3-VL-2B-Instruct)+ stage_a_distill.teacher_model: "Qwen/Qwen3.5-9B",代码路径已就绪;建议先在单卡 GPU 机器上冒烟 hf 路径,再上 Kaggle。