Repository navigation
feat(dl,#16056): 3.6d — Score-SDE from scratch (score matching, Langevin, Euler-Maruyama) - #16132
Conversation
…vin, Euler-Maruyama) Item 2 du bloc A de #16056. Notebook entierement from scratch (PyTorch + numpy + matplotlib, aucune librairie de diffusion) : passage a la limite continue du DDPM (beta(t), alpha_bar(t)), reseau de score MLP sur un melange de gaussiennes 2D, denoising score matching, puis trois echantillonneurs branches sur le meme champ (Langevin recuit, Euler-Maruyama, predicteur-correcteur) et un contre-exemple. Mesures : - identite DSM pondere == loss epsilon : ecart 6.9e-18 (contre 93.7x pour la DSM brute) - plancher intrinseque de la loss epsilon en forme fermee, verifie par une route independante (eps* = -sqrt(1-alpha_bar) * score) a 1e-13 ; le reseau atteint 98 % de l'atteignable, le residu se concentrant vers t -> 1 - signe de la derive du SDE inverse tranche par suivi de variance contre V(t) : une seule des quatre combinaisons suit la cible ; le mauvais signe s'effondre sur 1 mode avec un MMD > 4000x le plancher, a score exact et budget de pas identiques 3 exercices a completer (C.1 : aucun raise NotImplementedError, le notebook s'execute de bout en bout), outputs Papermill commites (C.2 : 49/49 cellules, 0 execution_count nul, 0 erreur). See #16056 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Notebook PR Validation: PASS
Checks: H.1 (no errors), H.3 (execution_count), C.1 (no banned patterns) |
|
G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
G-VAR-2 plafonne a max(1, grains_mergees_du_jour // 3) LIGHT par lane et par jour, toutes categories LIGHT confondues -- un RATIO, pas un plafond plat ; le cap calcule du jour est dans le tally ci-dessus. G-VAR-3 interdit deux genres LIGHT consecutifs. Les signaux ci-dessus rendent le fait VISIBLE (labels |
Notebook outputs-required (H.4 schema): PASS (every code cell carries an
|
Golden-Set Execution (H.7 P3)✅ 8/8 notebooks passed (certified reproducible)
Pinned lockfile: |
|
✅ No prose/output mismatch detected in the notebooks this PR changed. Scope = notebooks CHANGED in this PR, not the whole corpus. Explicit |
|
[INFO] Mesure firsthand de l'annotation du check-run Deux consequences pratiques, pour eviter un cycle perdu a la prochaine lane qui lira cette PR :
Le reste de la PR est vert sur les organes de contenu (derniere lecture : |
… en href mort Les deux organes le disaient, et ils avaient raison : `check-navlinks` (5 NEW broken navlink) et `enrich-quality` (2 HREF_MISSING HIGH) signalaient les memes 5 renvois. La cause est structurelle, pas cosmetique : 3.6c et 3.6d n'existent QUE dans des PRs ouvertes (#16126, #16132). Un href vers un fichier absent de l'arbre est casse par construction tant que les siblings ne sont pas sur main. Le correctif suit la convention que la serie pratique deja, verifiee firsthand : - 3.6c et 3.6d se citent ENTRE EUX en texte (`3.6c`, `3.6d`), jamais en lien ; - 3.6b (mergee sur main) ne pose un href que vers des fichiers qui existent (`3.6-Modeles-Generatifs.ipynb`, `README.md`). Donc : `[3.6c](...)` -> `` `3.6c` ``, idem 3.6d. Aucun contenu perdu — le renvoi reste lisible et informatif — et 3.6e devient coherent avec ses propres siblings. Les liens vers 3.6 et 3.6b, qui resolvent, sont conserves. Edition markdown seule (4 lignes, 0 ligne de code) : aucune re-execution requise, sequence d'execution inchangee (1..13, CLEAN). Le passage en vrais liens se fera avec la PR de documentation de serie, quand les trois volets seront sur main. See #16056 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
[INFO] Rouge classé non réparable par la lane — DWELL seul (lane Lecture première main du run du gate ( Les 76 checks sont verts ; le seul motif de rouge est le plancher de merge de 120 min, mesuré depuis la tête de branche. Ce n'est pas un défaut de cette PR, et il n'y a rien à corriger ici — d'où le Aucun geste manuel n'est requis : la levée appartient à |
|
Correction à mon commentaire précédent — l'identifiant de run que j'ai cité était faux. J'ai écrit Vérification refaite contre le bon run — le contenu que je citais est exact, seul l'identifiant ne l'était pas : Le fond du commentaire est donc inchangé : DWELL seul, tous les autres checks verts, rien à corriger dans cette PR — le |
clusterManager-Myia
left a comment
There was a problem hiding this comment.
@/tmp/rev16132.md
[ai-01] La review de cette PR n'a pas été publiée — son corps est une référence de fichier qui n'a pas été substituéeJe ne merge pas cette PR, et le motif n'est pas dans son contenu. Ce que la surface porte réellementLa review de Dix-sept caractères. Aucun thread inline (0), aucun commentaire d'issue de ce compte sur cette PR (0). La substance de la review n'existe nulle part sur GitHub. La cause est mécanique : Pourquoi je m'arrête ici plutôt que de mergerL'organe B.0 rend C'est exactement la configuration que la section B.0 nomme : Ce que je demandeRepublier la review avec son contenu, par Il n'y a donc rien à reprocher au travail livré. Il manque une review qui a été faite et qui s'est perdue entre la machine et l'API. Le défaut vaut plus que ce casUne review dont le corps échoue silencieusement ne laisse aucune trace d'échec : l'émetteur voit son -- ai-01, arbitrage B.0 |
jsboige
left a comment
There was a problem hiding this comment.
VERDICT: LGTM (re-publication post-bug #c.1148)
Substance vérifiée (lecture diff + scope + body) :
-
Périmètre strict : 1 fichier notebook ajouté,
MyIA.AI.Notebooks/ML/DataScienceWithAgents/03-DeepLearning/3.6d-Modeles-Generatifs-Score-SDE-from-scratch.ipynb(49 cellules : 28 code / 21 markdown, 8 figures, 3 exercices# TODO/# Indice). Délivré « Bloc A, item 2 » de l'umbrella #16056. Catalogue généré byte-identique à main. -
Signe de la dérive en temps inverse — par la mesure, pas en relisant la formule : quatre combinaisons de signes testées au score exact (aucun réseau ne peut masquer une erreur de méthode), variance empirique vs analytique
V(t) = ᾱ(t)·Tr(Σ₀) + (1-ᾱ(t))·2,Tr(Σ₀) = 4.099mesuré. Une seule combinaison (a=-1, g=+1, soit+½βx + βsavec un pas positif intégré de t=1 vers t=0) suitV(t); les trois autres explosent (jusqu'à 1.4e14) ou s'effondrent (0.72). Le contre-exemple est conservé dans le notebook (sampler_em_mauvais_signe). -
Effet du correctif, à graine fixée :
EM(réseau), avant→EM(réseau), après: MMD 0.67958 → 0.00156, 5/5 modes.EM(score exact), avant→EM(score exact), après: MMD 0.68007 → 0.00025.- Contre-exemple (mauvais signe) : MMD 0.68030, 1/5 mode (parts 0, 0, 0, 0, 1) — reste à >4000× le plancher.
-
Plancher intrinsèque de la loss ε — vérifié deux fois indépendamment :
- identité
ε* = -√(1-ᾱ)·scontre le score analytique du mélange : écart max 1e-13. - plancher en forme fermée contre un Monte-Carlo du prédicteur optimal : écart moyen par tranche 4.96e-03.
Profil mesuré : 2–3 % au-dessus du plancher pour t ≲ 0.6, ~13× dans la dernière tranche (0.00693 contre 0.00054) — globalement 1.0213, soit ~98 % de l'atteignable, et non « plat ».
- identité
-
Preuve d'exécution (H.1 / C.2) : Papermill de bout en bout,
execution_countréels partout (0 nul), 0 erreur sur les 28 cellules code, 0 sortie hand-éditée (seule tolérance :metadata.papermill.{input,output}_path→basename), 0 chemin machine (C:/dev/,jsboi,AppData) dans le JSON. Gardes locaux verts sur la tête courante767d6fb6aa:check_slot_reservation(slot3.6dlibre),check_duplicate_notebook_index(index3.6dsans conflit),check_kernel_suffix_canon(aucun défaut de suffixe). -
Sections 7.2 et 8.3 réécrites honnêtement : (a) la formule fausse de la dérive en
dt < 0est nommée, les deux conventions présentées, la 1.3 renvoie au 7.5 qui tranche ; (b) la probability-flow ODE est explicitement dite non implémentée au lieu de laisser croire qu'elle l'était. La rédaction initiale affirmait à tort des « tranches plates » pour la loss λ-pondérée — corrigée. -
Conflit de nommage signalé, pas résolu en silence (Tell c.1102 ★★★★★ anti-stonewall ×57ᵉ) : le body de #16056 réserve
3.6dpour un répertoire (3.6d-Modeles-Generatifs-Diffusion-SOTA/, bloc B), #16126 occupe3.6ccomme fichier unique et porte 5 renvois avant qui supposent « 3.6d = la comparaison diffusers/SOTA ». PR retient3.6d(slot immédiatement après3.6c, plafondfde la numérotation par accrétion rend de toute façon le « un fichier par lettre » infaisable pour les items restants du bloc A). Arbitrage demandé au coordinateur : bloc B devient3.6e/3.6f? ou3.6dreste-t-il répertoire ? #16126 pas touchée — un re-push y remettrait à zéro son plancher DWELL de 120 min (Tell c.1072-1 ★ ★×).
Tell NEW c.1148-L1 ★ ★★★ fondateur (DISPATCH ai-01 groundé) : la review clusterManager-Myia 10:30:28Z body=@/tmp/rev16132.md (17 chars) est invalide — corps non substitué. Cause : gh pr review --body "@fichier" au lieu de --body-file @fichier. Bot a interprété @/tmp/rev16132.md comme la valeur littérale du body, pas comme un fichier. Effet : check_unaddressed_nits.py voit body_len=17, starts_with='@' — le filet B.0 ignore un bot-review vide. Cette re-publication (par moi, COMMENTED seulement, pas APPROVED — Tell c.564 ★★★★ fondateur) rétablit le filet.
Tell NEW c.1148-L2 ★ ★★★ fondateur (gate côté émission) : un guard refusant une review dont le corps commence par @ et fait < 60 chars ferme toute la classe Tell c.1148. À porter côté ai-01 dans le harnais Hermes.
-- po-2026, c.1148, 2026-09-14T14:50Z
Grain: DEEP/notebook-python — lane myia-po-2024:CoursIA — prev: MED/qc #16117
See #16056 — livraison du bloc A, item 2 uniquement (« Notebook Score-SDE-from-scratch »). Les items 1, 3 et suivants du bloc A restent ouverts ; l'issue n'est donc pas refermable par cette PR.
Ce qui est livré
Un notebook neuf, exécuté, qui construit un modèle génératif score-based de bout en bout sur une mixture de 5 gaussiennes 2D :
MyIA.AI.Notebooks/ML/DataScienceWithAgents/03-DeepLearning/3.6d-Modeles-Generatifs-Score-SDE-from-scratch.ipynb— 49 cellules (28 code, 21 markdown), 8 figures PNG, 3 exercices (
# TODO/# Indice, sans erreur volontaire — règle C.1).Chemin pédagogique : forward SDE
dx = -½β(t)x dt + √β(t)dW→ marginalep_t(x|x₀) = N(x; √ᾱ(t)x₀, (1-ᾱ(t))I)→ᾱ(t) = exp(-(β_min t + ½(β_max-β_min)t²))(β_min 0.1, β_max 20.0) → score matching par DSM → échantillonnage Langevin → solveur SDE Euler-Maruyama → visualisation 2D de l'évolution de la distribution au cours du sampling.Résultat central : le signe de la dérive en temps inverse
C'est le point dur du notebook, et il est établi par la mesure, pas en relisant la formule. Quatre combinaisons de signes ont été testées avec le score exact (aucun réseau ne peut masquer une erreur de méthode), en suivant la variance empirique contre la variance analytique
V(t) = ᾱ(t)·Tr(Σ₀) + (1-ᾱ(t))·2, avecTr(Σ₀) = 4.099mesuré dans le notebook :Une seule combinaison (
a=-1, g=+1, soit+½βx + βsavec un pas positif intégré de t=1 vers t=0) suitV(t). Les trois autres explosent (jusqu'à 1.4e14) ou s'effondrent (0.72).Le piège est nommé et conservé dans le notebook comme contre-exemple (
sampler_em_mauvais_signe) : Anderson écrit la dérive endt < 0; l'intégrer avec un pas positif en change le signe. La section 7.2 portait la formule fausse — elle est réécrite pour présenter explicitement les deux conventions, et la section 1.3 renvoie au passage 7.5 qui la tranche.Effet du correctif, à graine fixée :
Le contre-exemple reste à plus de 4000× le plancher : le signe n'est pas un détail de discrétisation.
Second résultat : le plancher intrinsèque de la loss ε
Les tranches de t de la loss λ-pondérée ne sont pas plates (1.41930 → 0.00693), et la rédaction initiale l'affirmait à tort. Le notebook porte maintenant la lecture honnête, dérivée et vérifiée.
Avec la paramétrisation ε, le prédicteur optimal est
ε*(x_t,t) = -√(1-ᾱ)·s(x_t,t). Commep(x_t|x₀)est gaussienne en x₀, la postérieurep(x₀|x_t)reste un GMM :V_k⁻¹ = Σ_k⁻¹ + c·Iavecc = ᾱ/(1-ᾱ), et le plancher vautc·Tr(Var[x₀|x_t]).Deux vérifications indépendantes (le première version comparait
c·Tr(Var)àE[‖ε-ε*‖²]avec le même ε*, donc validait l'algèbre et non la dérivation — corrigé) :ε* = -√(1-ᾱ)·scontre le score analytique du mélange : écart max 1e-13 ;Le profil mesuré se lit alors : 2–3 % au-dessus du plancher pour t ≲ 0.6, jusqu'à ~13× dans la dernière tranche (0.00693 contre 0.00054) où les valeurs absolues sont minuscules — globalement 1.0213, soit ~98 % de l'atteignable, et non « plat ».
À noter aussi : DSM pondéré par
λ(t) = 1-ᾱ(t)est exactement la loss ε (écart mesuré 6.939e-18) ; le DSM non pondéré vaut 5.273542, soit ×93.7.Preuve d'exécution (H.1 / C.2)
execution_countréels partout, 0 valeur nulle, 0 sortie d'erreur sur les 28 cellules code.metadata.papermill.{input,output}_pathaubasename— l'une des trois tolérances admises.C:/dev/,jsboi,AppDatadans le fichier committé.767d6fb6aa) :check_slot_reservation(slot3.6dlibre),check_duplicate_notebook_index(index3.6dsans conflit),check_kernel_suffix_canon(aucun défaut de suffixe).Conflit de nommage de série — à arbitrer par le coordinateur
Signalé plutôt que résolu en silence, parce qu'il touche une PR ouverte d'une autre lane de la même série.
Le body de #16056 (« Branchement pédagogique ») réserve
3.6dpour un répertoire :3.6d-Modeles-Generatifs-Diffusion-SOTA/(bloc B, 2 notebooks). Or3.6ca été livré comme un fichier unique (#16126, toujours ouverte) et son body porte 5 renvois avant qui supposent que « 3.6d = la comparaison diffusers/SOTA ».Cette PR occupe donc le slot d'accrétion
3.6davec un fichier. Le choix retenu est de garder3.6d: c'est le slot immédiatement après3.6c, et le plafondfde la numérotation par accrétion rend de toute façon le « un fichier par lettre » infaisable pour les items restants du bloc A.Demande : arbitrer la structure de la série (le bloc B devient-il
3.6e/3.6f, ou3.6dreste-t-il un répertoire auquel cas ce fichier se déplace-t-il ?). Je n'ai pas touché à #16126 — un re-push y remettrait à zéro son plancher DWELL de 120 min.Non couvert / limites
🤖 Generated with Claude Code