feat(heads): incremental retraining — refit only changed tags (#1317 phase 2, m138)
train_all_heads is now incremental by default: a per-tag training-data fingerprint (positive + rejection count/latest-timestamp, stored on tag_head.train_fingerprint) means a manual Retrain refits ONLY the tags whose data changed — O(what you touched), not O(all heads). The nightly scheduled_train_heads passes full=True to reconcile sampled-negative + hygiene drift across every head. First incremental run after deploy still refits everyone (NULL fingerprints), stamping them, then it's incremental. The refit decision + fingerprint are split into sklearn-free helpers (_head_fingerprints, _heads_needing_retrain) so the incremental logic is unit-tested directly (train_head itself needs scikit-learn). Migration 0080. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CDgx8bQS5YrGRK76v8HUnM
This commit is contained in:
@@ -356,7 +356,10 @@ def scheduled_train_heads() -> str:
|
||||
if running is not None:
|
||||
return "already running"
|
||||
run = HeadTrainingRun(
|
||||
params={"source": "scheduled"}, status="running",
|
||||
# Nightly = FULL reconcile (refit every head) so sampled-negative +
|
||||
# hygiene drift is folded in; the manual Retrain button stays
|
||||
# incremental (#1317 p2).
|
||||
params={"source": "scheduled", "full": True}, status="running",
|
||||
last_progress_at=datetime.now(UTC),
|
||||
)
|
||||
session.add(run)
|
||||
|
||||
Reference in New Issue
Block a user