Training harness #49
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Parent
#37
What to build
A training orchestration script
sac_train.shthat drives SAC_LSTM_Bot training usingRunTraining.javafor match management.Responsibilities:
nimble build -d:releaseAcceptance criteria
sac_train.shcompiles the bot and launches training end-to-endBlocked by
Claimed for implementation (self-assigned as
SirStone— the MCP issue-edit surface here exposes no assignee field, so this comment is the assignment record). Working on branchresearch/goto-controller.Resolution — training harness (commit
df256b4)What was built
SAC_LSTM_Bot/sac_train.sh(new) — the orchestration script. Compiles the bot (nimble build -d:release) +RunTraining.java, then loops chunks: each chunk runs oneRunTraining.javabattle (CHUNK_SIZErounds, one battle per chunk so the bot's training thread survives rounds). Weighted opponent sampling per chunk, deterministic evaluation (SACLSTM_EVAL_MODE=1) everySAC_EVAL_INTERVALchunks with win-rate parsed from the runner's JSONL log, best checkpoint (weights/sac_best.zip+best_score.txt, persists across harness restarts) updated when the win rate improves, crash-restart loop (rerun chunk from latest checkpoint, abort afterSAC_MAX_CRASHESconsecutive). All knobs env-configurable:SAC_OPPONENTS("Name:weight,..."),SAC_TOTAL_ROUNDS,SAC_CHUNK_SIZE,SAC_EVAL_INTERVAL,SAC_EVAL_ROUNDS,SAC_EVAL_OPPONENT,SAC_MAX_CRASHES,SAC_LOG_FILE/SAC_EVAL_LOG_FILE;SACLSTM_*pass through to the bot.SAC_LSTM_Bot/SAC_LSTM_Bot.json+SAC_LSTM_Bot.sh(new) — launch packaging for the Tank Royale booter (<dir>/<dir>.json+<dir>.shconvention).src/SAC_LSTM_Bot/integration.nim—bumpRoundCounter(): one increment per round end toweights/round_counter.txt, the runner's liveness signal (best-effort: never raises into the event handler).opponentKey(): opponent identity helper (see below).src/SAC_LSTM_Bot.nim—onRoundEndedhandler callsbumpRoundCounter()(main thread).tools/training_runner/RunTraining.java— parameterized result matching viaBOT_NAMEenv (defaultPPO_Bot→ behavior for PPO_Bot unchanged). Strictly required: name matching was hardcoded.src/SAC_LSTM_Bot.json— self-reported name changed "Recurrent Royalty" → "SAC_LSTM_Bot". Found during smoke testing: the vendored API'sloadBotInfogives the json file total precedence over the booter'sBOT_NAMEenv, so a mismatch between the src json identity and the booter's dir-json identity makes the runner wait forever on a bot that actually connected ("connected 1 of 2, Pending: SAC_LSTM_Bot"). Identities must match; description in the json documents this.Opponent-ID resolution (Q14 follow-up)
tmkNewBattlestill carries the numericscannedBotId; the training thread now keys the "opponent changed → clear replay buffer" rule onopponentKey(id)=getBotName(id)when non-empty (v1.0.1 BotListUpdate table), falling back to the numeric id as string in the pre-BotListUpdate window. Caveat: until the first BotListUpdate arrives,getBotNamereturns""and the fallback key is the raw id — a same-id opponent across battles in that window keeps the buffer (safe, id-stable), but the id→name mapping may lag the very first battle of a process. Lookup happens training-side via the API's lock-guarded table — no strings cross thread boundaries (ORC rule from #48).How to run
Test status
nimble build+nimble test: 8/8 suites green.test_integration.nim: name-keyed NewBattle clear/keep (incl. numeric fallback via seededupdateBotNames) andbumpRoundCounterincrement/cold-start.weights/sac_latest.zipwritten by the bot's I/O thread, eval win rate parsed (0% vs untrained bot, expected),sac_best.zip+best_score.txtcreated, harness exit 0. Crash-recovery path observed live in an earlier run (bot identity mismatch → runner connect timeout → "crash #1/#2 — restarting chunk" loop engaged and aborted correctly at the configured limit).Notes / deliberate simplifications
<bot>/weights/sac_latest.zip(not env-overridable): RunTraining hardcodes the counter at$BOT_DIR/weights/, and the bot writes the counter next to its weights.SACLSTM_HIDDEN_SIZE=256updates are slow (~seconds/step at batch 16): real runs should tuneSACLSTM_SAVE_INTERVAL/SACLSTM_BATCH_SIZE/SACLSTM_HIDDEN_SIZEenv knobs; the smoke used hidden=32/batch=8/save=50 to exercise checkpointing in minutes.