From 5aab84c15f8a56c86c9f9a99dbdeecbf39e95124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=8B=9C=EC=9B=90?= Date: Thu, 7 May 2026 17:26:12 +0900 Subject: [PATCH] Only record evaluation_seconds when eval actually ran MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously the timer wrapped every call to _evaluate(), but on iterations that skip eval (iteration % eval_every != 0) the function returns immediately and the recorded value was just function-call overhead (~3 µs), which made W&B show a wildly bimodal "evaluation_seconds" metric. Now only set the key when eval_metrics is non-empty so non-eval iterations have no data point. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/coolrl_lost_cities/games/classic/deep_cfr/trainer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coolrl_lost_cities/games/classic/deep_cfr/trainer.py b/src/coolrl_lost_cities/games/classic/deep_cfr/trainer.py index f4dbbe1..4397c2e 100644 --- a/src/coolrl_lost_cities/games/classic/deep_cfr/trainer.py +++ b/src/coolrl_lost_cities/games/classic/deep_cfr/trainer.py @@ -325,7 +325,8 @@ class DeepCFRTrainer: eval_started = time.perf_counter() eval_metrics = self._evaluate(iteration) - self._runtime_metrics["evaluation_seconds"] = time.perf_counter() - eval_started + if eval_metrics: + self._runtime_metrics["evaluation_seconds"] = time.perf_counter() - eval_started self._runtime_metrics["advantage_memory_size"] = self._advantage_memory_size() for player, memory in enumerate(self.advantage_memories): self._runtime_metrics[f"advantage_player_{player}_memory_size"] = len(memory)