feat: enhance timeout handling in CoSTEER and DataScience scenarios (#1150)

* add prev loops to runner history

* fix evolving history

* fix bug on initializing feedback without final decision

* reformat

* refine

* add comments

* feat: enhance timeout handling in CoSTEER and DataScience scenarios

---------

Co-authored-by: Xu <v-xuminrui@microsoft.com>
This commit is contained in:
Xu Yang
2025-08-04 17:44:51 +08:00
committed by GitHub
parent 2426a1dc67
commit 811d4e7631
6 changed files with 24 additions and 6 deletions
+5 -2
View File
@@ -92,6 +92,7 @@ class CoSTEER(Developer[Experiment]):
# Evolving the solution
start_datetime = datetime.now()
fallback_evo_exp = None
reached_max_seconds = False
for evo_exp in self.evolve_agent.multistep_evolve(evo_exp, self.evaluator):
assert isinstance(evo_exp, Experiment) # multiple inheritance
if self._get_last_fb().is_acceptable():
@@ -103,6 +104,7 @@ class CoSTEER(Developer[Experiment]):
logger.info(f"evolving workspace: {sw}")
if self.max_seconds is not None and (datetime.now() - start_datetime).seconds > self.max_seconds:
logger.info(f"Reached max time limit {self.max_seconds} seconds, stop evolving")
reached_max_seconds = True
break
if RD_Agent_TIMER_wrapper.timer.started and RD_Agent_TIMER_wrapper.timer.is_timeout():
logger.info("Global timer is timeout, stop evolving")
@@ -111,13 +113,14 @@ class CoSTEER(Developer[Experiment]):
# if the final feedback is not finished(therefore acceptable), we will use the fallback solution.
try:
evo_exp = self._exp_postprocess_by_feedback(evo_exp, self._get_last_fb())
except CoderError:
except CoderError as e:
if fallback_evo_exp is not None:
logger.info("Fallback to the fallback solution.")
evo_exp = fallback_evo_exp
evo_exp.recover_ws_ckp() # NOTE: recovering checkpoints for restoring files in the workspace to prevent inplace mutation.
else:
raise
e.caused_by_timeout = reached_max_seconds
raise e
exp.sub_workspace_list = evo_exp.sub_workspace_list
exp.experiment_workspace = evo_exp.experiment_workspace
@@ -112,7 +112,13 @@ pipeline_coder:
```
In debug mode, your code should run faster, so the environment will set a shorter time limit than the standard time limit for your code.
For example, you can sample ten percent of the training data and run for one epoch, then the full run with ten epochs will take one hundred times the time taken for the debug run. The scale is calculated by yourself depending on the data sampling and epoch number you choose. If your full run enables early stopping, the scale should be smaller considering the early stopping will stop the training earlier than the full epochs.
Be careful about the train-valid split strategy. StratifiedShuffleSplit is highly risk since the data has some categories with only one sample. If you use StratifiedShuffleSplit, you should consider using a try-except block to catch the error and use a different split strategy if the error occurs.
Be careful about the train-valid split strategy. StratifiedShuffleSplit is highly risk since the data has some categories with only one sample. If you use StratifiedShuffleSplit, you should consider using a try-except block to catch the error and use a different split strategy if the error occurs. Example code:
```python
try:
fold_indices = StratifiedKFold(...).split(train_X, train_y) or StratifiedShuffleSplit(...).split(train_X, train_y)
except Exception as e:
fold_indices = KFold(...).split(train_X, train_y) or other split strategy
```
You should sample the data after train valid split. When you split the data after sampling, you might get a class with only one sample which might cause the split strategy to fail.
Your debug code should run exactly the same as the full run, except for the data sampling and epoch number, to ensure the correctness of the code.
You should print total time and estimated time in standard output using print function in the following schema: