Rétrospective S04 — LightGBM capacity ablation (Block 2)¶
KM / lessons learnt de la Story CVN-N001-EI-S04 (wp#227, GH #1059). Rédigée à la clôture (
Tested, deliverable conclu sur un négatif). Auditoire : l'équipe + le futur soi qui lancera le prochain diagnostic.
1. Objectif initial vs résultat réel¶
| Objectif | Tester si les défauts HPO de prod sur-ajustent (sur-capacité LGB) et recommander une config plus douce (HP swap). |
| Résultat | Verdict diagnostic B_SYSTEMATIC_OVERFIT (en val-AUC, 5/5). MAIS le deliverable HP-swap a fermé sur un NÉGATIF : la reco lr-doux ne transfère pas à l'objectif trading prod. + un incident hang 16 h résolu (fix infra) + 3 ADR durables. |
En une phrase : S04 a prouvé une existence (le signal sur-ajuste en AUC) mais s'est cassé en tentant une sélection (recommander lr=0.025) que seul l'objectif aval pouvait valider — et qui s'est révélée fausse.
2. Chronologie (la vraie histoire, pas la version lissée)¶
- Diagnostic construit, mergé, déployé (s42, two-layer Airflow+Hamilton).
- Premier full run figé 16 h (busy-wait livelock OpenMP/BLAS, 0 fit) → RCA confirmé Prometheus (pas « plausible », mesuré : ~3.2 cœurs/pod en busy-wait) → ADR-0096 (caps env-level threads+process) → PR #1097 → déploiement phasé WARN→observe→fail-loud → vérif 1 cellule → re-run.
- Re-run conclusif :
B_SYSTEMATIC_OVERFIT5/5 (ARBUSDC rattrapé sur learning_rate par le 5-axes que le smoke num_leaves ratait). - Deliverable HP-swap → cascade de §0bis :
- dérivation (trajectoire XCom) → stabilité multi-fold : seul
lrsurvit ;num_leaves/mcs= winner's curse (brillants in-sample, échouent OOS) ; - §0bis facteur : l'env-var
CVN_HPO_*_LEARNING_RATE≠ pin (Optuna cherche le RANGE) ; pas de mode no-HPO → la PR une-ligne était morte ; - §0bis verdict : prod cherche lr ∈ [0.05,0.15] sous f1_buy, pas l'AUC sur HP fixés → l'optimum ~0.025 est hors-range + hors-objectif ;
- §0bis lecture : objectif des runs mai non-vérifiable → bascule sur n=600 trials juin f1_buy-confirmés → la recherche prod ne favorise pas lr bas (médiane 0.106, 0% sous le plancher).
- Négatif documenté (« pas de support », sans brûler le compute B) + ADR-0097/0098/0099 + 4 Stories de suivi (S08-S11).
3. Lessons learnt¶
A. Méthodologiques (les durables)¶
-
La chaîne de validité des proxies — la leçon la plus fondamentale (et celle que cette rétro a failli rater). Le diagnostic optimise une chaîne de proxies : AUC → f1_buy → valeur économique. Chaque maillon est un proxy du suivant et doit une démonstration de transfert SÉPARÉE. S04 a appris (cher) que AUC → f1_buy ne transfère pas. Mais le maillon du haut — f1_buy → valeur économique — n'est aujourd'hui PAS démontré : f1_buy (f1 de la classe buy, seuillé) est lui-même un proxy du rendement net/expectancy, magnitude-aveugle (cf. A5), dont la fidélité à l'économique n'a jamais été établie. ⚠️ Fausse clôture à ne pas commettre : ADR-0098 valide un diagnostic contre l'objectif de déploiement (= f1_buy) — donc un diagnostic « correctement cadré » peut passer la gate tout en optimisant un proxy possiblement invalide. La couture diagnostic↔déploiement est fermée ; la couture déploiement↔valeur-économique reste OUVERTE — et c'est la plus fondamentale (ADR-0099 Inv 2 l'exige, elle n'est pas encore honorée). La leçon complète n'est donc pas « utilise f1_buy au lieu de l'AUC » (la demi-leçon qui refait l'erreur un cran plus haut) mais « valide chaque maillon de la chaîne ;
f1_buy → économieest le maillon ouvert à démontrer avant de s'y fier ». -
Existence ≠ sélection (ADR-0099). Un diagnostic (étape 1) prouve qu'un signal existe ; sélectionner la « meilleure » config exige l'objectif aval qu'il n'a pas. S04 a franchi cette frontière — c'est la leçon-mère. Sortie légitime d'un diagnostic = « X existe, d'ampleur Y », jamais « déploie Z ».
- Le diagnostic doit mapper le déploiement (ADR-0098) — sur métrique ET régime. s42 a mesuré l'AUC sur des HP fixés ; prod cherche sous f1_buy. Deux mismatches → verdict interne-valide mais hors-sujet pour décider.
- §0bis : 3 curatifs en exécution + 1 préventif ABSENT. Trois §0bis curatifs pendant l'exécution (facteur → verdict → lecture), chacun a rattrapé un faux positif. Mais le §0bis préventif de cadrage (« ce diagnostic mappe-t-il métrique+régime de la prod ? ») — une lecture de 10 min — n'a rien attrapé : il manquait au plan. La leçon de process n'est pas « on a fait 4 §0bis » mais « 3 curatifs ont rattrapé en exécution, cher, ce qu'1 préventif au plan aurait évité ». ADR-0098 = ce préventif, désormais plan-gate.
- Le proxy ne suit pas fidèlement l'objectif — NON-TRANSFERT (pas « anti-corrélation »). La sélection trading (recherche f1_buy) ne retient pas le lr bas que l'AUC préfère → l'AUC ne suit pas fidèlement f1_buy : non-transfert. ⚠️ Ne PAS dire « les optima pointent à l'opposé » — claim forte qu'on s'est explicitement interdite : lr est co-budgété avec
n_estimators(le lr-haut retenu peut refléter un re-budgeting, pas une préférence), et on n'a pas la courbe f1-vs-lr contrôlée. On ne réclame que ce qui est montré : le proxy peut ne pas transférer. Et — cf. A0 — f1_buy lui-même n'est qu'un maillon, pas la vérité économique. - « Sélectionner » réclame magnitude + objectif. Win-rate et f1 sont aveugles à la magnitude ; viser expectancy/edge net (ADR-0099 Inv 3).
B. Ce qui a marché (à répéter)¶
- Filtrage stabilité multi-fold asymétrique : a tué
num_leaves(5/5 in-sample, dérive OOS) sur le même critère quemcs— propre, symétrique. La contribution transférable (rapport publié). - Pré-enregistration de l'interprétation avant de lire (les 3 cas Q-objectif) — a gardé honnête un résultat satisfaisant (le plus dangereux).
- Read-only avant compute : la réfutation observationnelle a économisé tout le run B.
- RCA confirmé empiriquement (signature CPU Prometheus), pas une cause « plausible » non vérifiée.
C. Opérationnelles / pièges concrets (pour le prochain)¶
_generate_foldsestnow-anchored → un index de fold n'est pas reproductible cross-mois → pin les fenêtres calendaires, pas les index (et un run qui référence un fold doit tourner le même mois).- s42 exige l'axe primaire (
num_leaves) dansaxes_subset— un run mono-axe sortINCONCLUSIVE_TOOLING missing_primary_axis_probe. - L'XCom porte la trajectoire complète (
metrics.probes, dérivation sans re-run) ; mais MLflow ne logge pas l'objectif des runs et Loki ne retient pas > ~1 mois → vérifier l'objectif par run sur events récents (hpo_complete best_<metric>). reports/est gitignored (force-add) ; ajouter à la nav avant que le fichier soit tracké = build CI cassé ; lien vers fichier non-commité = strict-build passe en local, échoue en CI.- Thread caps : env-level
OMP/OPENBLAS/MKL/NUMEXPR_NUM_THREADS+LOKY_MAX_CPU_COUNT+OMP_WAIT_POLICY=passive, déploiement phasé WARN d'abord (blast-radius = tous les pods). - Scope / validité externe : tous les findings (verdict, distribution lr prod, négatif) sont
defi_top5-spécifiques ; généralisation à un autre univers/timeframe = non testée.
4. Ce qu'on change (process)¶
| Changement | Porté par |
|---|---|
| §0bis de cadrage au PLAN (le diagnostic mappe-t-il métrique+régime du déploiement ?) | ADR-0098 (plan-gate) |
| Frontière existence/sélection + lien de validité à chaque couture | ADR-0099 |
| Template rapport standardisé (pré-enregistration, limites first-class, reproductibilité) | ADR-0097 |
| Diagnostics suivants restent à l'existence | Epic §1bis |
Démontrer le maillon f1_buy → valeur économique (la couture la plus fondamentale, aujourd'hui OUVERTE — A0) avant de se fier à un diagnostic f1_buy-cadré |
ADR-0099 Inv 2 · à porter par/avant S11 |
5. Artefacts durables produits¶
- 3 ADR : 0097 (template rapport), 0098 (cadrage diagnostic↔déploiement), 0099 (architecture étagée existence≠sélection).
- 1 rapport publiable (méthodo réutilisable, anonymisé).
- 4 Stories de suivi : S08 (tooling), S09 (A6), S10 (re-cadrage), S11 (successeur). ⚠️ S11 mesure si la HPO f1_buy sur-ajuste — mais doit d'abord/en parallèle établir le maillon
f1_buy → valeur économique(A0), sinon il « correctement cadre » contre un proxy non démontré et refait l'erreur un cran plus haut. S11 n'est « correctement cadré » que s'il porte la chaîne complète, pas juste « mesurer f1_buy ». - Le fix infra (PR #1097 / ADR-0096) — réutilisé par tous les pods compute.
6. Verdict KM¶
Le deliverable scientifique de S04 = négatif (pas de HP swap). Mais le rendement net du fil = fortement positif : une leçon structurelle (existence≠sélection, proxy≠transfert), une méthode réutilisable, et des gates de process qui empêchent le prochain diagnostic de refaire l'erreur. Un négatif honnête + de la connaissance durable valent mieux qu'un faux positif déployé. C'est exactement ce que la discipline était censée produire.