Beyond data volume, use additional gates to ensure training quality and cost-efficiency:
- Task Distribution: Ensure corrections span multiple tasks to avoid overfitting to a specific task distribution (e.g., using a Gini coefficient for task coverage).
- Eval Set Stability: Ensure the evaluation set has not drifted since the last retrain to maintain comparable performance metrics.
- Human-in-the-loop: Print the retraining decision to stdout rather than auto-triggering to avoid unexpected GPU costs.
def should_retrain(state) -> tuple[bool, str]:
delta = state.corrected_episodes_since_last_train
corpus = state.cumulative_training_corpus
# Gate 1: Volume threshold (10%)
if delta < 0.10 * corpus:
return False, f"need 10% delta, have {delta/corpus:.1%}"
# Gate 2: Task distribution (avoid overfitting)
if state.task_coverage_gini > 0.5:
return False, "corrections concentrated in too few tasks"
# Gate 3: Eval set stability
if state.eval_set_changed_since_last_train:
return False, "eval set drifted, pin it before retraining"
return True, "ready"