Skip to content

fix(rag,#15677): RAG-03 exercices 1 et 2 — étiquetage depuis le vocabulaire de l'élève, perte normalisée par terme - #15756

Merged
myia-ai-01 merged 1 commit into
mainfrom
fix/15677-rag03-exercises
Sep 12, 2026
Merged

myia-ai-01 merged 1 commit into
mainfrom
fix/15677-rag03-exercises

Conversation

@jsboige

@jsboige jsboige commented Sep 12, 2026

Copy link
Copy Markdown
Owner

Ce que corrige cette PR

Grain: MED/notebook-python — lane myia-po-2023:CoursIA — prev: MED/guard #15753

#15677 : deux défauts confirmés dans 03-Embeddings-From-Scratch.ipynb, tous deux
dans les exercices de la section 8 — l'énoncé donnait à l'élève une instruction qui
plante
ou une grandeur qui ne mesure pas ce qu'elle annonce.

  1. Exercice 1 — étiquetage depuis le mauvais vocabulaire. L'étape 3 demandait
    plus_proches(normaliser(W_exo), w2i_exo[mot_sonde], k). Or plus_proches (cellule 14)
    étiquetait ses voisins depuis le vocabulaire global en dur, alors que w2i_exo
    indexe le corpus étendu de l'élève : indices décalés → mots rendus faux, et
    IndexError dès qu'un indice dépasse l'ancien corpus (les mots ajoutés y sont).
    Suivre l'énoncé à la lettre produisait donc soit un résultat silencieusement faux, soit
    un crash sur l'ajout de mots — le geste même de l'exercice.

  2. Exercice 2 — la comparaison lit un artefact d'échelle. L'énoncé invitait à comparer
    les courbes de perte brutes entre couples (D, K) — dont (30,2) / (50,5) /
    (100,10). La boucle de référence (section 4) accumule 1 + K termes par paire :
    l'échelle de la perte brute suit mécaniquement 1 + K (≈ (1+K)·ln 2 à
    l'initialisation), donc comparer des pertes brutes entre K différents mesure le
    compte de termes, pas l'effet de l'hyperparamètre.

Le fix

Cellule 14 — plus_proches gagne un paramètre etiquettes optionnel :

def plus_proches(vecteurs_normalises, indice, k=5, etiquettes=None):
    labels = vocabulaire if etiquettes is None else etiquettes
    ...
    return [(labels[j], round(float(sims[j]), 3)) for j in ordre[1:k+1] if j != indice]

Rétro-compatible : les appels existants (la cellule 14 elle-même, l'étape 1 de l'exercice 3
en cellule 28, qui travaillent sur le corpus global) gardent vocabulaire par défaut et
sont inchangés. Un commentaire explique le piège d'alignement indices↔étiquettes.

Cellules 23 / 24 (exercice 1) — l'étape 3 devient
plus_proches(normaliser(W_exo), w2i_exo[mot_sonde], k, etiquettes=vocabulaire_exo), et
l'énoncé gagne un paragraphe « Piège d'étiquetage, à traiter dans la solution » qui dit
pourquoi (indices décalés ; IndexError sur les mots nouveaux). L'exercice reste un
stub (C.1 : result = None, # TODO, # Étape N conservés) — c'est l'énoncé qui
devient correct, pas la solution qui est fournie.

Cellules 25 / 26 (exercice 2) — la comparaison se fait sur une perte normalisée par
terme
(perte / (1 + K)), avec l'artefact d'échelle expliqué dans l'énoncé et dans le
stub. Les exemples d'appel restent entrainer_exo(30, 2) / (50, 5) / (100, 10),
« à époques égales ». Stub inchangé côté C.1.

Validation

  • Ré-exécution complète post-édit (cellules code modifiées → règle C.2), avec le
    kernelspec déclaré du notebook (python3), via
    scripts/notebook_tools/notebook_tools.py execute :
[03-Embeddings-From-Scratch.ipynb] (kernel: python3)
  [+] SUCCESS                                    (EXECUTION SUMMARY, 55.5s)

cell 10 (entraînement, inchangé — RNG semé) :
  perte : époque 1 = 2.824 →  époque finale = 2.25
cell 24 : Exercice 1 à compléter : voisins de « tarte » après extension du thème (fonction autonome).
cell 26 : Exercice 2 à compléter : la courbe de perte pour (D, K) au choix, par appel explicite.
  • validate_pr_notebooks.py origin/main : 1/1 PASS (13 cellules code).
  • 13 cellules code, execution_count 1..13 (aucun null), 0 erreur.
  • C.1 : aucun raise NotImplementedError / assert False / 1/0 dans les sources ;
    les 3 stubs d'exercice gardent result = None, # TODO, # Indice, # Étape N.
  • Chemins machine : la ré-exécution via papermill estampille metadata.papermill ; les
    input_path/output_path absolus (D:\Dev\CoursIA-15677\...) ont été ramenés au
    basename par l'outil canonique scripts/notebook_tools/scrub_papermill_paths.py --apply
    (normalisation de metadata, pas un scrub de sortie). Re-scan : 0 défaut. Scan des
    sorties (--outputs) : aucune fuite.

Diff — ce qui bouge et pourquoi

Changement sourcé sur 5 cellules (14, 23, 24, 25, 26) : les 5 éditions ci-dessus.

Le reste du diff est le churn inhérent à une ré-exécution (C.2), vérifié cellule par
cellule contre origin/main :

cellule différence nature
11, 15 aucune — images byte-identiques matplotlib 3.10.3 = celui de la baseline
19 model_id du widget tqdm UUID de comm, unique par exécution
20 2.68e-07 → 2.53e-07 ordre de réduction BLAS sur un lot de 155 tokens ; la conclusion de la cellule (« masqué ≈ 1e-7 invariant vs brut ≈ 1.4 ») est identique
24 sortie stdout scindée en 2 blocs estampille papermill (newline final)

Note : 03-Embeddings-From-Scratch.ipynb ne portait aucune metadata papermill sur main ;
la ré-exécution en ajoute (notebook-level + par cellule). C'est la convention majoritaire de
la série (6/10 voisins la portent) et le produit direct de l'outil d'exécution du dépôt — je
le signale explicitement puisque cela élargit le diff au-delà des 5 cellules éditées.

Hors périmètre (respecté)

  • Aucune solution d'exercice fournie (les 3 stubs restent des stubs).
  • Aucune cellule d'exemple touchée ; W, Wc, vocabulaire, themes, phrases inchangés.
  • 1 fichier ; catalogue byte-identique à main.

See #15656 (PR ouverte touchant le même notebook, cellules non recouvrantes).

Closes #15677

🤖 Generated with Claude Code

…ulaire de l'eleve, perte normalisee par terme

Exercice 1 : plus_proches() gagne un parametre `etiquettes` optionnel
(defaut = vocabulaire global, retro-compatible) ; l'etape 3 de l'exercice
etiquette desormais depuis vocabulaire_exo, car w2i_exo indexe le corpus
etendu de l'eleve — les indices decales rendaient des mots faux et levaient
IndexError sur les mots ajoutes. L'enonce gagne le paragraphe "Piege
d'etiquetage".

Exercice 2 : la comparaison porte sur une perte normalisee par terme
(perte / (1 + K)), la boucle de la section 4 accumulant 1 + K termes par
paire — l'echelle de la perte brute suit (1 + K) mecaniquement (~ (1+K).ln 2
a l'initialisation), donc comparer des pertes brutes entre K differents
mesure le compte de termes, pas l'hyperparametre.

Re-execution complete (kernel declare python3) : 13 cellules code,
execution_count 1..13, 0 erreur ; validate_pr_notebooks 1/1 PASS ; les 3
stubs gardent result = None / TODO (C.1). Chemins absolus papermill ramenes
au basename via scrub_papermill_paths.py.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@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

✅ 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

Golden-Set Execution (H.7 P3)

✅ 8/8 notebooks passed (certified reproducible)

Notebook Status Time
2.1-Workflow-ML.ipynb ✅ SUCCESS 7.5s
2.2-Descente-de-gradient.ipynb ✅ SUCCESS 8.7s
2.3-Regression-lineaire-logistique.ipynb ✅ SUCCESS 10.6s
2.4-Arbres-Forets-Ensembles.ipynb ✅ SUCCESS 11.3s
Search-01-StateSpace.ipynb ✅ SUCCESS 7.7s
SL-1-LogicalLearning.ipynb ✅ SUCCESS 6.2s
rl_4_multi_armed_bandits.ipynb ✅ SUCCESS 59.1s
GameTheory-04c-NashExistence-Python.ipynb ✅ SUCCESS 6.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: 13
  • 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)

@github-actions

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359/#13615)

Cette PR #15756 (fix(rag,#15677): RAG-03 exercices 1 et 2 — étiquetage depuis le vocabulaire de l'élève, perte normalisée par terme) touche au moins un chemin de fichier aussi modifie par d'autres PRs ouvertes. Risque de double-livraison (meme fichier livre deux fois, 2x le travail et 2x les runs CI). Advisory : parfois legitime (tranches coordonnees, partition paths: explicite, PRs empilees exclues) -- l'organe rend visible, il ne bloque pas.

Le verdict terminal (#15578) signifie que la substance est deja sur main : le cote merge n'est plus une collision a arbitrer, c'est du travail deja integre.

@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.

VERDICT: LGTM (vérifié: rétrocompatibilité plus_proches + correction mathématique de l'artefact d'échelle (1+K)·ln 2)

[Hermes] — review du head c47893cf (aucune review cluster pré-existante sur ce SHA).

Vérifications effectuées :

  • Fix 1 rétrocompatible et complet : plus_proches(..., etiquettes=None) avec labels = vocabulaire if etiquettes is None else etiquettes — les 4 sites d'appel du diff vérifiés : la définition, les indices de l'énoncé ex. 1 ; les appels de démonstration de la section 4 utilisent le défaut (vocabulaire global), comportement inchangé. Le diagnostic de l'issue est cohérent : w2i_exo indexe le corpus étendu → étiquettes globales = mots faux + IndexError au-delà de l'ancien corpus.
  • Fix 2 — la correction est mathématiquement juste : la perte skip-gram à K négatifs accumule bien 1+K termes par paire (terme positif + K négatifs), chacun ≈ ln 2 à l'initialisation → perte brute ≈ (1+K)·ln 2. Comparer des pertes brutes entre K∈{2,5,10} mesure le compte de termes, pas l'hyperparamètre. L'énoncé corrigé (« perte MOYENNE PAR TERME — perte_par_epoque / (1 + K) ») et l'explication ajoutée à l'élève sont exactes.
  • Stubs préservés : les 2 cellules exercices restent des TODO (result = None) — aucun output de « solution » fabriqué ; la ré-exécution intégrale du notebook est fraîche (timestamps iopub.execute_input 2026-09-12, papermill.exception: false sur toutes les cellules). Le +421 se décompose en ~176 lignes de churn papermill/timestamps, 16 lignes substantives (nouveau paramètre + énoncés), le reste en fermetures JSON.
  • Security scan : 0 match.

Rien de bloquant.

@myia-ai-01
myia-ai-01 merged commit e7d2cfe into main Sep 12, 2026
77 of 79 checks passed
jsboige added a commit that referenced this pull request Sep 12, 2026
…ulaire de l'eleve, perte normalisee par terme (#15756)

Exercice 1 : plus_proches() gagne un parametre `etiquettes` optionnel
(defaut = vocabulaire global, retro-compatible) ; l'etape 3 de l'exercice
etiquette desormais depuis vocabulaire_exo, car w2i_exo indexe le corpus
etendu de l'eleve — les indices decales rendaient des mots faux et levaient
IndexError sur les mots ajoutes. L'enonce gagne le paragraphe "Piege
d'etiquetage".

Exercice 2 : la comparaison porte sur une perte normalisee par terme
(perte / (1 + K)), la boucle de la section 4 accumulant 1 + K termes par
paire — l'echelle de la perte brute suit (1 + K) mecaniquement (~ (1+K).ln 2
a l'initialisation), donc comparer des pertes brutes entre K differents
mesure le compte de termes, pas l'hyperparametre.

Re-execution complete (kernel declare python3) : 13 cellules code,
execution_count 1..13, 0 erreur ; validate_pr_notebooks 1/1 PASS ; les 3
stubs gardent result = None / TODO (C.1). Chemins absolus papermill ramenes
au basename via scrub_papermill_paths.py.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants