feat(SAC_LSTM_Bot): training harness (#49)
sac_train.sh orchestrates chunked self-play via tools/training_runner/ RunTraining.java: weighted opponent sampling per chunk, deterministic eval (SACLSTM_EVAL_MODE=1) every N chunks with win-rate tracking, best checkpoint (weights/sac_best.zip) by eval score, crash-restart loop on the runner's liveness detection. Supporting changes: - integration.nim: opponentKey() keys the NewBattle buffer-clear rule on getBotName(id) with numeric-id fallback (#49 Q14 follow-up); bumpRoundCounter() emits the per-round liveness signal. - SAC_LSTM_Bot.nim: onRoundEnded -> bumpRoundCounter(). - RunTraining.java: BOT_NAME env parameterizes result matching (default PPO_Bot, unchanged behavior for PPO). - Launch packaging: root SAC_LSTM_Bot.json + .sh for the booter; src json name aligned to 'SAC_LSTM_Bot' so self-reported identity matches the booted identity (mismatch = runner connect timeout).
This commit is contained in:
@@ -18,9 +18,10 @@ import java.util.logging.Logger;
|
||||
* to the same log file via PPOB_LOG_FILE — the shell wrapper stitches them.
|
||||
*
|
||||
* Usage (env vars):
|
||||
* PPO_BOT_DIR — path to PPO_Bot dir
|
||||
* PPO_BOT_DIR — path to the bot dir (any Tank Royale bot)
|
||||
* SAMPLE_BOTS_DIR — path to sample bots archive
|
||||
* PPOB_LOG_FILE — path to training_log.jsonl (appended)
|
||||
* BOT_NAME — bot name to match in round results (default: PPO_Bot)
|
||||
* TRAINING_OPPONENT — opponent bot name (default: Target)
|
||||
* TRAINING_ROUNDS — number of rounds to run (CLI arg or env var)
|
||||
*
|
||||
@@ -39,8 +40,9 @@ public class RunTraining {
|
||||
: System.getenv().getOrDefault("TRAINING_OPPONENT", "Target");
|
||||
int totalRounds = args.length > 1 ? Integer.parseInt(args[1])
|
||||
: Integer.parseInt(System.getenv().getOrDefault("TRAINING_ROUNDS", "100"));
|
||||
String botName = System.getenv().getOrDefault("BOT_NAME", "PPO_Bot");
|
||||
|
||||
System.out.printf("Training: PPO_Bot vs %s for %d rounds%n", opponent, totalRounds);
|
||||
System.out.printf("Training: %s vs %s for %d rounds%n", botName, opponent, totalRounds);
|
||||
System.out.printf("Log: %s%n", logFile);
|
||||
|
||||
// Dead-bot guard: the runner keeps listing a crashed PPO_Bot in the
|
||||
@@ -81,7 +83,7 @@ public class RunTraining {
|
||||
boolean win = false;
|
||||
boolean found = false;
|
||||
for (var r : event.getResults()) {
|
||||
if (r.getName().equals("PPO_Bot")) {
|
||||
if (r.getName().equals(botName)) {
|
||||
found = true;
|
||||
totalScore = r.getTotalScore();
|
||||
win = r.getRank() == 1;
|
||||
@@ -99,9 +101,9 @@ public class RunTraining {
|
||||
frozenRounds[0]++;
|
||||
long frozenMs = System.currentTimeMillis() - lastAdvanceMs[0];
|
||||
if (frozenRounds[0] >= 10 && frozenMs >= 10_000) {
|
||||
System.err.printf("PPO_Bot round_counter frozen at %d for %d "
|
||||
System.err.printf("%s round_counter frozen at %d for %d "
|
||||
+ "harness rounds / %.0fs — process dead, aborting for restart%n",
|
||||
ctr, frozenRounds[0], frozenMs / 1000.0);
|
||||
botName, ctr, frozenRounds[0], frozenMs / 1000.0);
|
||||
System.exit(1);
|
||||
}
|
||||
} else {
|
||||
@@ -110,7 +112,7 @@ public class RunTraining {
|
||||
lastAdvanceMs[0] = System.currentTimeMillis();
|
||||
}
|
||||
if (!found) {
|
||||
System.err.println("PPO_Bot missing from round " + round
|
||||
System.err.println(botName + " missing from round " + round
|
||||
+ " results — process died, aborting battle for restart");
|
||||
System.exit(1);
|
||||
}
|
||||
@@ -147,10 +149,10 @@ public class RunTraining {
|
||||
endCounter = readCounter(counterPath);
|
||||
}
|
||||
if (endCounter < expectedEnd) {
|
||||
System.err.printf("PPO_Bot round_counter %d < expected %d (start+%d) at battle "
|
||||
System.err.printf("%s round_counter %d < expected %d (start+%d) at battle "
|
||||
+ "end (waited 60s) — %d rounds never trained (corpse?), aborting for "
|
||||
+ "restart%n",
|
||||
endCounter, expectedEnd, totalRounds, expectedEnd - endCounter);
|
||||
botName, endCounter, expectedEnd, totalRounds, expectedEnd - endCounter);
|
||||
System.exit(1);
|
||||
}
|
||||
System.out.printf("Counter check passed: %d == expected %d%n", endCounter, expectedEnd);
|
||||
|
||||
Reference in New Issue
Block a user