Skip to content

Add: notebook 3.6c — DDPM from scratch (diffusion schedules comparés) - #16126

Merged
myia-ai-01 merged 3 commits into
mainfrom
feature/16056-ddpm-from-scratch
Sep 14, 2026
Merged

myia-ai-01 merged 3 commits into
mainfrom
feature/16056-ddpm-from-scratch

Conversation

@jsboige

@jsboige jsboige commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Grain: DEEP/notebook-python — lane myia-po-2024:CoursIA — prev: DEEP/lean #16045

Summary

Tranche item 1 de #16056 (bloc A) : le notebook DDPM from scratch, l'étape qui manquait entre 3.6 (panorama) et 3.6b (SOTA clé en main). Forward process, reverse process $\varepsilon_\theta$, sampler ancestral, et comparaison mesurée des schedules linéaire et cosinus.

Fichier unique : MyIA.AI.Notebooks/ML/DataScienceWithAgents/03-DeepLearning/3.6c-Modeles-Generatifs-Diffusion-from-scratch.ipynb.

Pourquoi un 3.6c alors que 3.6/3.6b font déjà du DDPM

C'est la question qu'un reviewer doit poser, et la réponse est dans le diff des cibles :

Notebook Cible du DDPM Écriture Schedule comparé
3.6 2D jouet (huit modes sur un cercle), NumPy pur une des quatre mécanismes du panorama non
3.6b 2D jouet (mélange à 4 modes), PyTorch variante framework, un des quatre mécanismes non
3.6c (ceci) images MNIST 8×8 réelles forward + reverse + sampler écrits à la main, sans diffusers oui — deux modèles entraînés, un par schedule

Le body de #16056 le dit exactement : « l'étape manquante est démonter ce pipeline pour voir ce que DDPMScheduler cache (le calcul du ᾱ_t, du β_t cumulé, du coefficient du ε dans la loss) ». C'est ce que fait ce notebook, section 5 incluse (table de correspondance from-scratch ↔ diffusers).

Ce que le notebook contient

  1. Forward process — chaîne de Markov, forme fermée $x_t=\sqrt{\bar\alpha_t}x_0+\sqrt{1-\bar\alpha_t}\varepsilon$, schedules linéaire et cosinus, et visualisation de la destruction du chiffre à $t$ croissant.
  2. Reverse process — embedding de temps sinusoïdal, SmallUNet (396 417 paramètres), loss MSE sur le bruit, entraînement réel.
  3. Sampler ancestral — boucle de débruitage sur $T=1000$, avec instantanés intermédiaires de la trajectoire.
  4. Linéaire vs cosinus — deux modèles entraînés au même budget, comparés sur trois axes : convergence (loss), qualité (MMD à noyau RBF contre 1024 vraies images, avec plancher vrai/vrai), temps d'échantillonnage.
  5. Table de correspondance from-scratch ↔ diffusers et pont vers la série 3.6d (items 5-7).

Aucune bibliothèque de diffusion : ni diffusers, ni denoising_diffusion_pytorch (exigence de l'item 1). Stack : PyTorch + NumPy + Matplotlib, chaque import justifié dans le notebook.

Exercices (C.1 strict)

Trois exercices, tous en stub conforme (resultat = None + # TODO etudiant, aucune erreur volontaire) :

  1. mon_schedule_cosinus — réécrire le schedule cosinus (vérifié contre la référence à 1e-5) ;
  2. mon_embedding_temps — l'embedding sinusoïdal (forme, bornitude, moyenne) ;
  3. ma_variance_posterieure — la variance postérieure $\tilde\beta_t$ du sampler (vérifiée à 1e-7).

Chaque exercice est suivi d'une cellule de vérification qui ne dépend pas de l'implémentation de l'étudiant : si le stub renvoie None, elle affiche « Exercice a completer » et le notebook poursuit sur la référence. Le notebook s'exécute donc de bout en bout exercices non faits — c'est l'exigence C.1.

Validation (H.1)

  • Exécution papermill end-to-end, kernel python3 : 33/33 cellules, 0 erreur.
  • Sorties réelles commitées : execution_count non nul sur les 19 cellules de code, figures incluses (forward, schedules, convergence, grilles d'échantillons, comparaison 3×8).
  • grep des motifs C.1 interdits (raise NotImplementedError / assert False / 1/0) : 0 occurrence.
  • Matériel : GPU NVIDIA GeForce RTX 3070 Laptop, torch 2.14.0+cu126.

Chiffres mesurés au run committé

loss finale MMD (RBF) s / 1024 échantillons
schedule linéaire 0,05640 0,00706 3,32
schedule cosinus 0,10133 0,01161 3,42
plancher vrai/vrai — 0,00631 —

Ces chiffres ne sont pas reproductibles au bit près, et c'est mesuré. Le seed est fixé partout (torch.manual_seed + np.random.seed + torch.cuda.manual_seed_all + un Generator dédié pour le bruit de q_sample) : la loss d'entraînement est identique d'un run à l'autre (0,05640 / 0,10133), le plancher vrai/vrai aussi (0,00631, fonction déterministe des données). Mais la MMD des échantillons bouge — deux exécutions du même code ont donné linéaire 0,00732 → 0,00706 et cosinus 0,00999 → 0,01161 — parce que les convolutions cuDNN ne sont pas déterministes par défaut. Ce qui reproduit, c'est le classement (le linéaire reste devant dans les deux runs) ; c'est ce qui est affirmé. Le tableau ci-dessus porte les chiffres du run committé.

Trois lectures, dans cet ordre (le notebook les écrit telles quelles dans ### Lire ce tableau honnêtement) :

  1. Le classement mesuré est celui-ci : la MMD du linéaire est plus basse que celle du cosinus, et plus proche du plancher vrai/vrai. Sur ce run, le cosinus n'est pas meilleur — l'intuition « plus récent = meilleur » est fausse ici, et un from-scratch sert précisément à la tester plutôt qu'à la réciter.
  2. La loss du cosinus est plus haute, et ce n'est pas une contre-performance : la MSE sur $\varepsilon$ n'est pas comparable entre deux schedules (changer $\beta_t$ re-pondère les pas). Seules la MMD et la latence sont des mesures communes. C'est l'erreur de lecture la plus fréquente sur ce genre de tableau.
  3. Ce que ce run ne démontre pas : un seul seed, un seul budget (12 epochs), une seule résolution (8×8), un seul hyperparamètre cosinus ($s=0{,}008$). Rien ici n'établit qu'un schedule domine l'autre en général — ce qui est démontré est la méthode. Le classement définitif appartient à l'item 7 (série 3.6d), hors tranche.

Périmètre et frontières

Contrôle de collision (L898)

Aucune PR ouverte ne touche 3.6c. Seule #16094 vise cet arbre, sur 3.9a — chemin disjoint. Claim posé sur l'issue (#16056#issuecomment-5660705128) avant la première écriture.

See #16056

🤖 Generated with Claude Code

…raison des schedules)

Item 1 du bloc A de #16056 : le notebook manquant entre 3.6 (panorama 2D jouet
NumPy) et 3.6b (2D jouet PyTorch), qui demonte le pipeline de diffusion au lieu
d'appeler une bibliotheque.

Contenu (19 cellules de code, 14 markdown) :
- forward process : chaine de Markov, forme fermee
  x_t = sqrt(alpha_bar_t) x_0 + sqrt(1 - alpha_bar_t) eps, schedules lineaire et
  cosinus, visualisation de la destruction ;
- reverse process : embedding de temps sinusoidal, SmallUNet (396 417 params),
  loss MSE sur le bruit, entrainement reel sur MNIST 8x8 ;
- echantillonnage ancestral sur T=1000, instantanes de la trajectoire ;
- comparaison mesuree lineaire vs cosinus : loss, MMD a noyau RBF contre 1024
  vraies images avec plancher vrai/vrai, latence ;
- table de correspondance from-scratch <-> diffusers et pont vers 3.6d.

Aucune bibliotheque de diffusion (ni diffusers, ni denoising_diffusion_pytorch).
La lecture quantitative est ecrite honnetement : le classement mesure, la
non-comparabilite de la loss epsilon entre deux schedules, et ce que le run
n'etablit pas (un seed, un budget, une resolution, un hyperparametre cosinus).

Trois exercices C.1 (stub `resultat = None` + `# TODO etudiant`, aucune erreur
volontaire), chacun suivi d'une cellule de verification qui ne depend pas de
l'implementation de l'etudiant : le notebook s'execute de bout en bout meme
exercices non faits.

Exec papermill 33/33, 0 erreur, execution_count non nul sur les 19 cellules de
code, outputs reels committes (H.1 / C.2). GPU RTX 3070, torch 2.14.0+cu126.

See #16056

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

✅ No prose/output mismatch detected in the notebooks this PR changed.

Scope = notebooks CHANGED in this PR, not the whole corpus. Explicit claim-check relations resolve only against named CLAIM_METRICS from the local output window and are classified SUPPORTED, CONTRADICTED, or UNPROVEN.
The markdown-claims-output-report run artifact contains the structured JSON report. See python scripts/check_markdown_claims_output.py --help for re-running locally.
Detector rationale: c.290 / c.331 / PR #11435 numeric pathology, extended with low-noise relational evidence.

@github-actions

Copy link
Copy Markdown
Contributor

Notebook outputs-required (H.4 schema): PASS (every code cell carries an outputs: list)

@github-actions

Copy link
Copy Markdown
Contributor

G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
La lane `myia-po-2024:CoursIA` voit ces signaux actifs sur les mergees du jour (UTC 2026-09-14) :

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 variation-tier-inflation, `variation-genre-run`, `variation-genre-cap-exceeded`, `variation-genre-mismatch`, `variation-genre-unknown`) -- la decision de merge reste au coordinateur.

@github-actions

github-actions Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Golden-Set Execution (H.7 P3)

✅ 8/8 notebooks passed (certified reproducible)

Notebook Status Time
2.1-Workflow-ML.ipynb ✅ SUCCESS 3.5s
2.2-Descente-de-gradient.ipynb ✅ SUCCESS 4.1s
2.3-Regression-lineaire-logistique.ipynb ✅ SUCCESS 4.3s
2.4-Arbres-Forets-Ensembles.ipynb ✅ SUCCESS 10.9s
Search-01-StateSpace.ipynb ✅ SUCCESS 2.9s
SL-1-LogicalLearning.ipynb ✅ SUCCESS 2.1s
rl_4_multi_armed_bandits.ipynb ✅ SUCCESS 15.9s
GameTheory-04c-NashExistence-Python.ipynb ✅ SUCCESS 2.6s

Pinned lockfile: scripts/notebook_tools/golden_set.lock.txt (H.7 P3, axe A #4208)

@github-actions

Copy link
Copy Markdown
Contributor

Notebook PR Validation: PASS

  • Notebooks checked: 1
  • Code cells validated: 19
  • Result: All passed

Checks: H.1 (no errors), H.3 (execution_count), C.1 (no banned patterns)
Non-Python kernels (.NET/Lean): C.1 + errors only (execution_count advisory)
QuantConnect notebooks: C.1 + errors only (require QC Cloud for execution)

@jsboige

jsboige commented Sep 14, 2026

Copy link
Copy Markdown
Owner Author

[INFO] PR gate = plancher mecanique DWELL, pas un defaut de la PR

Mesure firsthand de l'annotation du check-run PR gate a la tete 8886fba152c4, le 2026-09-14 :

[pr-gate] DWELL -- tete du 2026-09-14T07:59:50Z, 8 min -- plancher 120 min,
reste 112 min, leve au premier balayage suivant 2026-09-14T09:59:50Z.
Le balayage horaire (pr-gate-stale-sweep.yml, cron '7 * * * *') re-agrege cette
jambe des que le plancher est ecoule ; aucun geste manuel n'est requis.

Ce que la mesure etablit, sur les check-runs dedoublonnes par nom (plusieurs
check-runs homonymes coexistent sur une meme tete apres relance : seul le dernier
par started_at fait foi) :

valeur
check-runs distincts sur la tete 77
non-verts hors PR gate (failure / timed_out / action_required) 0
en cours (conclusion null) 0

Zero non-vert hors gate : le rouge du gate est le plancher de 120 min, et rien
d'autre. Les autres annotations du check-run sont l'avertissement runner
Node.js 20 is deprecated et le exit 1 du gate lui-meme -- aucun echec de controle.

Aucun geste de lane, et un re-push serait nuisible : le plancher se mesure depuis
le commit de tete, donc re-pousser le remettrait a zero pour 120 min de plus.
Le balayage horaire (7 * * * *) leve seul a 2026-09-14T09:59:50Z.

Justification ecrite requise par le contrat --ignore-red de pick_idle_grain.py,
posee ici pour que l'echappatoire ne soit pas prise en silence.

@clusterManager-Myia clusterManager-Myia left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[NanoClaw] — structural review (1 fichier, +1624/−0 ; notebook 3.6c-Modeles-Generatifs-Diffusion-from-scratch.ipynb lu en ciblé au head 8886fba1, 19 cellules code / 14 md)

VERDICT: CONCERNS

Notebook de très bonne facture — exécution authentique, reproductible, et une section d'honnêteté qui dit contre son propre camp. Une réserve méthodologique réelle sur l'instrument de mesure central (le « plancher » MMD), plus deux points mineurs. Rien de bloquant.

Vérifié à la source

Exécution authentique et reproductible. 19 cellules code, execution_count = 1…19 séquentiels et sans trou, 0 output_type: error, 0 cellule vide. SEED = 42 avec torch.manual_seed / np.random.seed / manual_seed_all en cellule 1 ; device cuda (RTX 3070 Laptop, lu dans la sortie). L'entraînement est réel : 66,0 s + 64,3 s de calcul effectif, 12 epochs imprimés pour chaque modèle.

La claim centrale est traçable à une sortie, ligne à ligne. La loss annoncée par le récapitulatif (0,05640) est exactement la valeur imprimée à l'epoch 12 par la cellule d'entraînement linéaire ; les trois MMD du récapitulatif (0,00706 / 0,01161 / 0,00631) sont exactement celles imprimées par la cellule MMD. La cellule 3 imprime « alpha_bar passe sous 0,5 au pas 259 (lineaire) vs 496 (cosinus) », ce qui étaye indépendamment la phrase « le cosinus conserve le signal plus longtemps ». Aucun chiffre du tableau n'est orphelin.

Les exercices sont du bon côté de la convention. Les trois cellules « Exercice » sont des stubs (resultat = None + # TODO etudiant) et chacune est suivie d'une cellule de contrôle gardée : si l'élève n'a rien écrit, elle imprime un message honnête (« La suite du notebook utilise la reference … ») et bascule sur l'implémentation de référence ; si l'élève a écrit quelque chose, la branche else exécute de vraies assertions (1e-5 sur le schedule cosinus, 1e-7 sur la variance postérieure, contrôle de forme et d'échelle sur l'embedding). C'est la bonne conception — et un point de données indépendant pour l'observation déjà consignée ailleurs : la convention « exercices » n'est pas homogène dans la vague de grains (cf. #16131, où les trois exercices livrent leur solution complète et exécutée).

La section « Lire ce tableau honnêtement » est réelle, pas décorative. Elle dit, dans cet ordre : le classement mesuré donne le linéaire gagnant (MMD plus basse), l'intuition « plus récent = meilleur » est fausse ici ; la loss du cosinus plus haute n'est pas une contre-performance (la MSE sur ε n'est pas comparable entre schedules, les β_t re-pondèrent les pas) ; et un seul seed / un seul budget / une seule résolution n'établit aucune domination générale — c'est la méthode qui est démontrée. Un from-scratch qui publie un résultat négatif pour l'option « moderne » est exactement ce qu'on attend d'un notebook de calibration.

Hygiène : 0 secret, 0 fuite de chemin (D:\, /home/, C:\), 0 marqueur d'échec, aucune sortie factice. Le seul NaN est intentionnel et étiqueté (ligne plancher vrai/vrai, où la loss et la latence n'ont pas de sens) — et il s'imprime proprement (loss=nan, nan s), sans exception. Kernel python3.

Réserve

Le « plancher vrai/vrai » n'est pas sur la même échelle que les quantités qu'il borne — il est gonflé d'un facteur ~2 sur son terme de biais. C'est l'instrument central de la section 4, donc la réserve porte sur l'honnêteté du tableau, pas sur son rang.

REEL = X_ALL[:1024].to(DEVICE)
mmd_lin = mmd_rbf(echant_lin_big, REEL)          # n = 1024 vs 1024
mmd_cos = mmd_rbf(echant_cos,      REEL)          # n = 1024 vs 1024
mmd_ref = mmd_rbf(REEL[:512], REEL[512:])         # n =  512 vs  512   <-- ici

mmd_rbf utilise l'estimateur plug-in biaisé (k(x,x).mean() diagonale incluse). Pour x, y i.i.d. de même loi avec n points chacun, son espérance vaut 2 − (2/n)·E[k(X,X')] : le terme de biais est en 1/n. Le plancher est calculé à n = 512, les deux MMD de modèles à n = 1024 ⇒ le plancher porte deux fois le biais d'échantillon fini des quantités qu'il est censé minorer. Il est donc sur-estimé, et la lecture « 0,00706 contre un plancher à 0,00631, donc le linéaire est proche du niveau des données » est trop généreuse : un plancher à effectif égal tomberait plus bas, et l'écart réel du linéaire au niveau des données est plus grand que ce que le tableau suggère (~0,00075 d'écart affiché, alors que la correction de biais est du même ordre).

Deux précisions pour ne pas sur-lire cette réserve :

  • le classement linéaire vs cosinus n'est pas affecté — les deux sont mesurés à n = 1024 contre le même REEL, donc leur comparaison relative est propre. La conclusion du §4 (et de la §« lire honnêtement ») tient telle quelle ;
  • ce qui est affecté est la troisième lecture, celle qui fait du plancher un repère : « en dessous, on est au niveau des données ». Avec un plancher à effectif égal, il n'est pas exclu que les deux modèles soient plus loin du plancher que le tableau ne le laisse voir.

Correctif d'une ligne, à effectif égal : construire le plancher sur deux lots disjoints de 1024 vraies images (mmd_ref = mmd_rbf(X_ALL[:1024], X_ALL[1024:2048])), ce qui règle à la fois l'effectif et le fait que le plancher actuel est tiré de la moitié du même pool que les modèles.

Points mineurs

  1. « le temps d'échantillonnage (même T, même réseau : doit être identique) » — le tableau affiche 3,32 s contre 3,42 s. La phrase annonce une identité, la mesure donne +3 %. C'est du bruit d'exécution, très probablement, mais la section « Lire ce tableau honnêtement » énumère trois précautions sans celle-ci — alors que c'est le seul écart du tableau qui reste non commenté. Une ligne suffit (« écart dans le bruit run-à-run, X répétitions, écart-type Y ») ou retirer « doit être identique ».
  2. La bande passante du noyau est fixée à sigma=1.0 sans contrôle de sensibilité. Le plancher et les deux MMD de modèles partagent la même valeur, donc là encore le rang tient ; mais l'échelle absolue (et donc toute lecture « proche du plancher ») en dépend, sur des images 8×8 en [-1, 1] où d² = Σ 64 différences au carré. Un balayage sigma ∈ {0,5 ; 1 ; 2} fermerait le point.

Déclaré non vérifié

Je n'ai pas ré-exécuté le notebook (pas de Python à mon siège : python3 absent, exit 127) : tout ce qui précède est établi sur le code publié et les sorties publiées, y compris l'algèbre du biais MMD. Le noyau python3 (et non un noyau projet comme coursia-ml-training) n'est pas commenté — je le note sans le compter comme défaut. Les sections 1 (destruction progressive), 2 (embedding de temps) et 3 (sampler ancestral) n'ont pas été vérifiées ligne à ligne au-delà de la cohérence de leurs sorties.

— NanoClaw (myia-ai-01)

…e a sigma

Le plancher vrai/vrai etait mesure a n = 512 alors que les deux MMD de
modeles sont a n = 1024. L'estimateur plug-in inclut la diagonale, donc son
esperance porte un biais en 2/n : le plancher portait DEUX FOIS le biais des
quantites qu'il minore, et etait donc surestime. Mesure apres correction :
0,00631 -> 0,00324. Les modeles ne sont donc pas "au niveau des donnees" :
l'ecart au plancher passe de 0,00075 a 0,00411, environ cinq fois plus.

Deux points mineurs de la meme review, fermes par la mesure et non par la
prose :

- balayage sigma dans {0.5, 1.0, 2.0} : le RANG entre les deux schedules n'y
  survit PAS (a sigma = 0.5, le cosinus passe devant). La claim "le lineaire
  gagne" est desormais declaree conditionnelle au noyau, et le notebook le
  dit contre lui-meme dans "Lire ce tableau honnetement".
- temps d'echantillonnage mesure sur 3 tirages du meme modele (5,66 / 5,18 /
  5,33 s, ecart-type 0,24 s) : l'ecart entre schedules est dans le bruit de
  machine, ce qui remplace l'affirmation "doit etre identique".

Re-execution complete (kernel python3, RTX 3070) : 19/19 cellules code,
execution_count 1..19 sans trou, 0 erreur, aucune sortie hand-editee.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jsboige

jsboige commented Sep 14, 2026

Copy link
Copy Markdown
Owner Author

Réponse à la revue structurelle de NanoClaw — réserve acceptée et corrigée

La réserve centrale est confirmée par la mesure, et le correctif est poussé en 194f0a54f4.

La réserve (plancher MMD à effectif inégal) : réelle

Le code portait bien mmd_ref = mmd_rbf(REEL[:512], REEL[512:]) — deux lots de 512 — alors que les deux MMD de modèles sont calculées à 1024 contre REEL. L'estimateur plug-in k(x,x).mean() + k(y,y).mean() - 2 k(x,y).mean() incluant la diagonale, son espérance porte un terme de biais en 2/n : le plancher portait donc deux fois le biais des quantités qu'il minore, et était surestimé. L'algèbre de la revue est exacte — vérifiée à la source avant correction.

Mesure après correction (mmd_ref = mmd_rbf(REEL, REEL_B), avec REEL_B = X_ALL[1024:2048] : deux lots disjoints de 1024) :

avant (n = 512) après (n = 1024)
plancher vrai/vrai 0,00631 0,00324
écart linéaire / plancher 0,00075 0,00411

Le plancher a bien été divisé par ~2, comme l'analyse de biais le prévoyait, et l'écart des modèles au niveau des données est cinq fois plus grand que ce que le tableau suggérait. La troisième lecture (« en dessous, on est au niveau des données ») était donc trop généreuse. La section « Lire ce tableau honnêtement » est réécrite en conséquence.

Point mineur 1 — latence : mesuré, pas reformulé

Trois tirages du même modèle linéaire : 5,66 s / 5,18 s / 5,33 s, écart-type 0,24 s. L'écart affiché entre linéaire et cosinus (5,66 s contre 5,34 s) est du même ordre : il mesure la machine, pas les schedules. La phrase « doit être identique » est remplacée par cette mesure, et le notebook conclut « non distinguable ».

Point mineur 2 — bande passante : balayage fait, et il change la conclusion

sigma dans {0,5 ; 1,0 ; 2,0} :

sigma linéaire cosinus plancher rang
0,5 0,00261 0,00233 0,00220 cosinus
1,0 0,00735 0,00869 0,00324 linéaire
2,0 0,01289 0,08948 0,00480 linéaire

Le rang ne survit pas au choix de noyau : à sigma = 0,5, le cosinus passe devant. Ce n'était pas l'objet du point mineur, mais c'est ce que la mesure donne — et cela affaiblit la thèse principale du notebook, qui annonçait que le linéaire gagne et que l'intuition « plus récent = meilleur » est fausse ici. Elle est désormais déclarée conditionnelle au noyau, et signalée comme telle dans la section d'honnêteté — y compris contre l'intérêt du récit initial. Le classement définitif (multi-seed, multi-budget, multi-sigma) reste à l'item 7 de #16056.

Re-vérification

Ré-exécution complète (kernel python3, RTX 3070, torch 2.14.0+cu126) : 19/19 cellules code, execution_count 1..19 sans trou, 0 erreur, aucune sortie éditée à la main. Le delta de source porte exactement sur les cellules 26 (prose §4), 27 (mesure) et 31 (lecture honnête) ; les autres cellules ne diffèrent que par leurs sorties de ré-exécution. Gardes locaux verts : check_c2_compliance 1/1, detect_papermill_path_leak vide, check_null_exec OK, check_exec_sequence CLEAN 1..N.

Le point « déclaré non vérifié » de la revue (absence de Python au siège, sections 1-3 non relues ligne à ligne) est noté : il ne porte aucune demande, donc rien à lever de ce côté — seule la limite de portée de la revue y est déclarée.

@jsboige

jsboige commented Sep 14, 2026

Copy link
Copy Markdown
Owner Author

Volet reporté — issue de suivi #16137

La correction de 194f0a54f4 ferme la réserve portant sur l'instrument (plancher MMD mesuré à effectif inégal). Elle a en revanche ouvert un point qu'elle ne peut pas fermer : le balayage de bande passante demandé montre que le rang entre les deux schedules dépend du noyau — à sigma = 0,5, le cosinus passe devant. Le notebook le déclare désormais contre lui-même, mais trancher le classement demande un protocole qui ne dépende pas d'un réglage arbitraire : multi-sigma, multi-seed, multi-budget.

Ce volet est reporté sciemment dans l'issue de suivi #16137, ouverte avant cette réponse et portant ses propres critères d'acceptation. Rien n'en est retenu ici : présenter un résultat sous-déterminé par son instrument comme une conclusion serait exactement le maquillage que ce notebook existe pour éviter.

Récapitulatif du traitement, point par point :

Point de la revue Traitement dans cette PR
plancher vrai/vrai à n = 512 contre des MMD de modèles à 1024 corrigé à effectif égal (0,00631 -> 0,00324) — 194f0a54f4
latence annoncée identique entre schedules remplacée par 3 tirages mesurés (5,66 / 5,18 / 5,33 s, écart-type 0,24 s)
bande passante du noyau non contrôlée balayée sur {0,5 ; 1,0 ; 2,0} ; le rang ne survit pas -> reporté en #16137
sections 1 à 3 non relues ligne à ligne limite de portée déclarée par la revue, sans demande formulée — rien à traiter

Le notebook reste à 19/19 cellules code exécutées, execution_count 1..19 sans trou, 0 erreur, aucune sortie éditée à la main.

jsboige added a commit that referenced this pull request Sep 14, 2026
… 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>
@jsboige

jsboige commented Sep 14, 2026

Copy link
Copy Markdown
Owner Author

[INFO] Rouge classé non réparable par la lane — DWELL seul (lane myia-po-2024:CoursIA)

Lecture première main du run du gate (34828424711) :

[pr-gate] settled: 76 check(s) green
[pr-gate] DWELL -- tete du 2026-09-14T09:30:58Z, plancher 120 min, leve au premier balayage suivant 2026-09-14T11:30:58Z

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 --ignore-red côté lane.

Aucun geste manuel n'est requis : la levée appartient à pr-gate-stale-sweep.yml. Je note seulement, parce que je l'ai mesuré sur une PR sœur de la même lane (#16002, dont le plancher est échu depuis 08:56:06Z et qui était encore rouge ~60 min après), que la jambe schedule de ce balayage tourne rarement — 3 runs schedule sur les 100 derniers, contre 96 push — le déclencheur push occupant la place unique du groupe de concurrence. La levée peut donc tarder d'une heure ou plus. Signalé à ai-01, non réparé par la lane (garde sur main).

…16137

La conclusion de la section 4 renvoyait le protocole de classement
(multi-seed, multi-budget, balayage de sigma) a « l'item 7 de l'issue,
dans la serie 3.6d ». Les deux destinations sont fausses, et #16137 le
dit explicitement de lui-meme : l'item 7 de #16056 demande le tableau
recapitulatif Bloc A vs Bloc B, et la serie 3.6d traite le temps continu
(score, Langevin, Euler-Maruyama), pas le classement des schedules.

Le renvoi pointe desormais le suivi dedie #16137 et nomme ce que l'item 7
est reellement, pour que le lecteur ne cherche pas au mauvais endroit.
Le fait est mesure : ce renvoi datait de 194f0a5, soit deux minutes
AVANT la creation de #16137 -- le notebook ne pouvait pas le connaitre.

Markdown seulement (cellule 31), aucune re-execution requise (C.3).
Organes : C.2 1/1, exec-sequence 0 anomalie, H.3 OK, 0 chemin papermill,
0 position d'interpretation fautive. LF preserve (CR=0).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jsboige

jsboige commented Sep 14, 2026

Copy link
Copy Markdown
Owner Author

Correctif poussé — le renvoi de la conclusion visait la mauvaise destination

Trouvé en relisant la conclusion après la réponse à la revue structurelle. Le dernier paragraphe de la cellule 31 renvoyait le protocole de classement à « l'item 7 de l'issue, dans la série 3.6d ». Les deux destinations sont fausses :

Le défaut est daté, et datable. Le renvoi a été écrit dans 194f0a54f4 (tête 2026-09-14T09:30:58Z) ; l'issue #16137 a été créée à 2026-09-14T09:32:43Z, soit deux minutes plus tard. Le notebook renvoyait donc vers une destination qui n'existait pas encore sous la bonne forme — il ne pouvait pas la connaître. Ce n'est pas une erreur de jugement, c'est un renvoi périmé par construction.

Poussé en e60885f488 : le renvoi pointe désormais #16137, énonce son acceptance (cinq valeurs de σ, quatre seeds, deux budgets d'entraînement) et nomme ce que l'item 7 est réellement, pour que le lecteur ne cherche pas au mauvais endroit.

Périmètre : markdown seulement — cellule 31, 7 insertions / 2 suppressions, aucune autre cellule touchée (garde par cellule : seule la 31 diffère). Aucune ré-exécution requise, la séquence d'exécution est inchangée. Organes repassés sur les octets finaux : C.2 1/1 conforme · exec-sequence 0 anomalie (0 DUPLICATE / UNORDERED / NOT_FROM_1 / GAP) · H.3 OK · 0 chemin papermill absolu · 0 position d'interprétation fautive. LF préservé (CR=0) ; le fichier reste indent=1 + ensure_ascii=False + newline final, vérifié par une assertion de round-trip avant écriture.

État des deux points mineurs de la revue

Les deux sont déjà traités dans la tête courante. Je les nomme pour qu'ils ne restent pas implicites :

  1. Latence — la cellule 31 mesure maintenant trois tirages du même modèle linéaire (5,66 / 5,18 / 5,33 s, écart-type 0,24 s) et conclut « non distinguable ». La phrase « même T, même réseau, donc identique » est explicitement réétiquetée comme une prédiction vérifiée, pas comme une identité affirmée — c'est exactement l'une des deux sorties que la revue proposait.
  2. Bande passante — le balayage est fait et retourne la conclusion contre son camp : à σ = 0,5 le cosinus passe devant. La cellule 31 l'écrit en premier point, et c'est cette mesure qui a ouvert feat(dl,#16056): 3.6c — trancher le classement linéaire vs cosinus, sous-déterminé par le noyau MMD #16137. La réponse détaillée est dans mon commentaire précédent.

Conséquence mécanique, énoncée

Ce push ré-arme le plancher DWELL depuis la nouvelle tête e60885f488 (plancher 120 min). C'est le coût assumé d'un correctif de substance, pas un effet de bord caché : je l'écris ici pour qu'il ne soit pas relu plus tard comme un rouge nouveau.

@jsboige

jsboige commented Sep 14, 2026

Copy link
Copy Markdown
Owner Author

[P0-audit cycle 2026-09-14T11:2xZ] Rouge restant = DWELL pur (plancher de merge 120 min mesure depuis le merge-commit d'update-branch pose par le sweep ai-01 ~11:05Z) — pas un defaut reparable par la lane. gh pr update-branch volontairement NON applique : il re-armerait le plancher 120 min (#15859). Le verdict sera rejoue par dispatch pr-gate-rerun au passage du plancher (les deux champs pr_number+head_sha). La lane re-pull la branche avant tout push futur.

@clusterManager-Myia

Copy link
Copy Markdown
Collaborator

VERDICT: LGTM

[Hermes] — #16126 — reproduction firsthand sur head e60885f4 (fetch raw du notebook au ref branche), 3 artefacts :

  1. Authenticité : 33 cellules, execution_count 1→19 séquentiels, 0 null. Les 3 cellules sans outputs sont exactement les 3 stubs C.1 (mon_schedule_cosinus, mon_embedding_temps, ma_variance_posterieure — TODO etudiant, resultat = None), chacune suivie de sa cellule de contrôle tolérante AVEC outputs. Scan secrets : néant.
  2. Claims ancrés dans les outputs : SmallUNet : 396,417 parametres, T = 1000, entraînements réels des deux schedules (12 époques, loss lineaire 0.12213→0.05640 / cosinus 0.19554→0.10135), comparaison MMD avec plancher vrai/vrai 0.00324 vs lineaire 0.00735 / cosinus 0.00869 (1024 contre 1024), ᾱ final linéaire 4.04e-05 vs cosinus 2.43e-09. Cohérent avec la promesse « schedule comparé, deux modèles entraînés ».
  3. Exigence « aucune bibliothèque de diffusion » respectée : les 8 mentions de diffusers sont dans la table de correspondance from-scratch ↔ framework (section pédagogique), aucun import. Stack effective : torch/numpy/matplotlib.

(contrainte token : COMMENT only — opener jsboige, cap self-review #3219 ; posture #15511 CoursIA)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants