#!/usr/bin/env python3 """openpi config.py に deep_even10_v1 (位置 1〜5 を各 10 本にそろえた 50 本) 用の学習設定を足す (2026-11-09 依頼 133. lab_train.sh --model deep1. 依頼 135 で --variant b (lab_train.sh --model deep1b) を足した). π0.5 base から新しく学習する (続きの学習ではない). 中身は trim の pi05_mecharm_trim_lora と同じ LoRA・batch 32・ 学習率の予定 (warmup 300 / peak 5e-5 / decay_lr 5e-6)・weight_loader (π0.5 base) で, 次の所だけ変える (add_trim_config.py と同じ方式): name pi05_mecharm_trim_lora -> --variant v1: pi05_mecharm_deep_even10_lora --variant b: pi05_mecharm_deep_even10_b_lora repo_id local/mecharm_redblock_box_teach_v1_trim2 -> local/mecharm_redblock_box_deep_even10_v1 num_train_steps 4_000 -> --steps (依頼 133 は 3000) decay_steps 5_000 -> --variant v1: 5_000 のまま (依頼 133 の 2999 はこれで学習した) --variant b: --steps と同じ (依頼 135. 学習の終わりで decay_lr まで下げきる) 正規化の値は写さず, Pod で compute_norm_stats.py をこの設定で回して測り直す (pod_prep_deep.sh). install_addon.py と add_trim_config.py (lab/Log11/pod/) を実行した後に 1 回実行: python3 add_deep_config.py /workspace/openpi --steps 3000 --variant b 何度実行しても同じ結果 (二重に入れない). 入っている設定と --steps が違うときは止まる. v1 と b は名前が違うので両方入れられる. """ import argparse import re import sys from pathlib import Path REPO_ID = "local/mecharm_redblock_box_deep_even10_v1" TRIM_A = " # >>> r2r2r mecharm teach_v1_trim2 (train config)\n" TRIM_B = " # <<< r2r2r mecharm teach_v1_trim2 (train config)\n" BASE_LOADER = 'weight_loader=weight_loaders.CheckpointWeightLoader("gs://openpi-assets/checkpoints/pi05_base/params"),' TRIM_DECAY = "decay_steps=5_000," WARMUP = 300 # trim と同じ warmup_steps. decay_steps はこれより大きくないと下げる区間がない # trim と同じであることを確かめる値 (写したあとも変わっていないこと). decay_steps は --variant ごとに見る SAME_AS_TRIM = ("batch_size=32,", f"warmup_steps={WARMUP},", "peak_lr=5e-5,", "decay_lr=5e-6,", BASE_LOADER) # --variant ごとの設定の名前・印・decay_steps (None は --steps と同じ) VARIANTS = { "v1": {"name": "pi05_mecharm_deep_even10_lora", "mark": "deep_even10_v1", "decay": 5000}, # 依頼 133 (今回の 2999) "b": {"name": "pi05_mecharm_deep_even10_b_lora", "mark": "deep_even10_v1 b", "decay": None}, # 依頼 135 } # 依頼 133 の形を残す (テスト・ほかから読む名前) NAME = VARIANTS["v1"]["name"] def marks(variant): m = VARIANTS[variant]["mark"] return (f" # >>> r2r2r mecharm {m} (train config)\n", f" # <<< r2r2r mecharm {m} (train config)\n") MARK_A, MARK_B = marks("v1") def decay_of(variant, steps): d = VARIANTS[variant]["decay"] return steps if d is None else d def decay_text(n): """openpi の書き方に合わせる (5000 -> 5_000)""" return f"decay_steps={n:_}," def make_block(s, steps, variant="v1"): assert s.count(TRIM_A) == 1 and s.count(TRIM_B) == 1, "先に install_addon.py と add_trim_config.py を実行する" block = s[s.index(TRIM_A):s.index(TRIM_B) + len(TRIM_B)] ma, mb = marks(variant) reps = [ (TRIM_A, ma), (TRIM_B, mb), ('name="pi05_mecharm_trim_lora"', f'name="{VARIANTS[variant]["name"]}"'), ('repo_id="local/mecharm_redblock_box_teach_v1_trim2"', f'repo_id="{REPO_ID}"'), ("num_train_steps=4_000,", f"num_train_steps={steps},"), (TRIM_DECAY, decay_text(decay_of(variant, steps))), ] for a, b in reps: assert block.count(a) == 1, f"見つからない/重複: {a!r}" block = block.replace(a, b) for x in SAME_AS_TRIM: assert block.count(x) == 1, f"trim の設定に見つからない: {x!r}" return block def main(argv=None): ap = argparse.ArgumentParser() ap.add_argument("openpi_root") ap.add_argument("--steps", type=int, required=True, help="学習のステップ数 (num_train_steps. 依頼 133 は 3000)") ap.add_argument("--variant", choices=sorted(VARIANTS), required=True, help="v1 = decay_steps 5_000 (依頼 133 の 2999) / b = decay_steps を --steps と同じに (依頼 135)") args = ap.parse_args(argv) if args.steps <= 0: sys.exit("[ERROR] --steps は 1 以上") decay = decay_of(args.variant, args.steps) if decay <= WARMUP: sys.exit(f"[ERROR] decay_steps ({decay}) が warmup_steps ({WARMUP}) 以下. --steps を大きくする") name = VARIANTS[args.variant]["name"] ma, mb = marks(args.variant) cfg = Path(args.openpi_root).resolve() / "src" / "openpi" / "training" / "config.py" s = cfg.read_text() if ma in s: have = s[s.index(ma):] have = have[:have.index(mb)] m = re.search(r"num_train_steps=(\d+),", have) if not (f'name="{name}"' in have and f'repo_id="{REPO_ID}"' in have and all(x in have for x in SAME_AS_TRIM)): sys.exit("[ERROR] 入っている設定の名前・データ名・学習の値が違う. openpi の config.py を git checkout してから入れ直す") if not (m and int(m.group(1)) == args.steps): sys.exit("[ERROR] 別の --steps で入っている. openpi の config.py を git checkout してから入れ直す") if have.count(decay_text(decay)) != 1: sys.exit(f"[ERROR] 入っている設定の decay_steps が {decay} ではない. openpi の config.py を git checkout してから入れ直す") print("already installed (config.py は変更なし)") return 0 if f'name="{name}"' in s: sys.exit(f"[ERROR] {name} がもう別の形で入っている. openpi の config.py を git checkout してから入れ直す") block = make_block(s, args.steps, args.variant) j = s.index(TRIM_B) + len(TRIM_B) cfg.write_text(s[:j] + block + s[j:]) print(f"installed: {name} (repo_id={REPO_ID}, {args.steps} steps, decay_steps {decay}, init=π0.5 base)") return 0 if __name__ == "__main__": sys.exit(main())