malkhut(perf): parallel episode eval — 9x single-eval speedup, zero fidelity loss
- parallel_eval.py: ProcessPoolExecutor-based episode runner. Each worker gets its own CWM + planner instance. Zero shared state = embarrassingly parallel. Deterministic: same seed → same result. - PolicyEvaluator.evaluate_candidate: new workers parameter (0=sequential, >1=parallel). Backward compatible: default workers=0. - 16 new tests: determinism, pickling, result validity, cross-validation between sequential and parallel paths, backward compatibility. - README: training performance table with speedup measurements. Speedup results (3 assets × 30 scenarios = 90 scenarios): Sequential: 3.3s per eval (1.0x) 2 workers: 1.3s per eval (2.6x) 4 workers: 0.6s per eval (5.9x) 8 workers: 0.4s per eval (9.1x) CMA-ES 48 evals: 125s → 85s (1.5x training speedup) Note: CWM numba hot path was already wired (_HAS_NUMBA=True, 5.3µs/transition). Bottleneck is MCTS planner (96% of eval time), not CWM.
This commit is contained in:
@@ -963,11 +963,17 @@ class PolicyEvaluator:
|
||||
planner_type: str = "sm_mcts",
|
||||
record_to_matrix: bool = False,
|
||||
matrix: Optional[Any] = None,
|
||||
workers: int = 0,
|
||||
) -> Tuple[float, list[EpisodeResult]]:
|
||||
results: list[EpisodeResult] = []
|
||||
for scenario in scenarios:
|
||||
result = self._run_episode(params, scenario, rng_seed, planner_type)
|
||||
results.append(result)
|
||||
if workers > 1 and len(scenarios) > 1:
|
||||
from malkhut.training.parallel_eval import ParallelEpisodeRunner
|
||||
runner = ParallelEpisodeRunner(workers=workers)
|
||||
results = runner.run_episodes(params, scenarios, rng_seed, planner_type)
|
||||
else:
|
||||
results = []
|
||||
for scenario in scenarios:
|
||||
result = self._run_episode(params, scenario, rng_seed, planner_type)
|
||||
results.append(result)
|
||||
# TIE-IN: Record strategy × regime performance
|
||||
if record_to_matrix and matrix is not None:
|
||||
tags = scenario.tags
|
||||
|
||||
Reference in New Issue
Block a user