Skip to content

Commit b70729f

Browse files
jrruijliThe kauldron Authors
authored andcommitted
Add eval_until_step option to Kauldron evaluations
PiperOrigin-RevId: 914132571
1 parent 29aeaca commit b70729f

3 files changed

Lines changed: 41 additions & 6 deletions

File tree

kauldron/evals/eval_impl.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,9 @@ def _preemptable_iter_new_checkpoints(
176176
state: train_step.TrainState,
177177
) -> Iterator[train_step.TrainState]:
178178
"""Yields the new checkpoints."""
179-
# Skip the `iter_new_checkpoints` for eval-only jobs.
180-
if trainer.setup.eval_only:
179+
# Skip the `iter_new_checkpoints` for eval-only jobs ONLY IF
180+
# eval_until_step is not set.
181+
if trainer.setup.eval_only and trainer.setup.eval_until_step is None:
181182
return
182183

183184
trainer_ckpt = trainer.checkpointer
@@ -196,6 +197,17 @@ def _preemptable_iter_new_checkpoints(
196197
# state might have been donated, we should not access it after this point.
197198
# Eval is done, remove the duplicated checkpoint
198199
eval_ckpt.delete(step)
200+
# Exit if resumed step meets or exceeds limit
201+
if (
202+
trainer.setup.eval_until_step is not None
203+
and step >= trainer.setup.eval_until_step
204+
):
205+
logging.info(
206+
f'Resumed step {step} reaches eval_until_step'
207+
f' {trainer.setup.eval_until_step}. Exiting.'
208+
)
209+
return
210+
199211
for step in trainer_ckpt.iter_new_checkpoints(
200212
min_interval_secs=10,
201213
timeout=10,
@@ -222,6 +234,17 @@ def _preemptable_iter_new_checkpoints(
222234
if trainer.setup.preemptable_eval:
223235
eval_ckpt.delete(step)
224236

237+
# Simply break the loop if we have evaluated the max step
238+
if (
239+
trainer.setup.eval_until_step is not None
240+
and step >= trainer.setup.eval_until_step
241+
):
242+
logging.info(
243+
f'Reached eval_until_step {trainer.setup.eval_until_step}.'
244+
' Stopping.'
245+
)
246+
break
247+
225248

226249
def _restore_checkpoint(
227250
*,

kauldron/train/setup_utils.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class Setup:
5050
`Writer`, to ensure all dashboards are written to the same collection.
5151
eval_only: Whether the job is a eval-only job.
5252
preemptable_eval: If `True`, makes eval preemptible.
53+
eval_until_step: If set, limits the evaluation to only evaluate checkpoints up to this step.
5354
"""
5455
# pyformat: enable
5556

@@ -60,6 +61,7 @@ class Setup:
6061
eval_only: bool = False
6162
# TODO(epot): Not the best place for this.
6263
preemptable_eval: bool = False
64+
eval_until_step: int | None = None
6365

6466
def __post_init__(self):
6567
# Normalize tags to a list.

kauldron/xm/_src/kauldron_utils.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,10 @@ def _resolve_run_konfig(
215215
# Cannot use `dataclasses.replace` as it interact with the `merge_utils`
216216
run = type(run)(**init_kwargs)
217217

218+
eval_until_step = kontext.get_by_path(
219+
self._cfg, "setup.eval_until_step", None
220+
)
221+
218222
if self._is_eval_only: # Eval only, normalize run config.
219223
if isinstance(run, run_strategies.AlongTrain):
220224
run = run_strategies.StandaloneLastCheckpoint(
@@ -226,10 +230,16 @@ def _resolve_run_konfig(
226230
init_kwargs = dict(run._kxm_init_kwargs) # pylint: disable=protected-access
227231
init_kwargs.pop("job_group", None) # Avoid duplicated kwarg.
228232

229-
run = run_strategies.StandaloneLastCheckpoint(
230-
job_group=run.job_group,
231-
**init_kwargs,
232-
)
233+
if eval_until_step is not None:
234+
run = run_strategies.StandaloneEveryCheckpoint(
235+
job_group=run.job_group,
236+
**init_kwargs,
237+
)
238+
else:
239+
run = run_strategies.StandaloneLastCheckpoint(
240+
job_group=run.job_group,
241+
**init_kwargs,
242+
)
233243
else:
234244
raise TypeError(
235245
f"Unexpected run strategy for {eval_name}. Got: {type(run)}."

0 commit comments

Comments
 (0)