Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,13 @@
"print(f\"ratio : {n_params(teacher) / n_params(student):>6.1f}x\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lecture** : Verbatim : « maitre : 235146 params », « eleve : 26506 params », « ratio : 8.9x », et sur le test « maitre : acc=0.8906 ece=0.0362 params=235146 [42s] ». Attention à l'attribution : 89,06 % est l'exactitude du MAÎTRE, pas de l'élève compressé. Le tableau final (section 8) donne le vrai trade-off : maitre 235146 params / 920.8 KB / 1.24 ms / acc 0.8906 / ECE 0.0362 ; baseline 26506 / 105.8 KB / 0.19 ms / 0.7948 / 0.0736 ; **distille** 26506 / 105.8 KB / 0.23 ms / **0.8132 / 0.0462**. Neuf fois plus petit que le maître, +1,8 point et mieux calibré que l'élève seul — c'est la distillation. Prudence sur la latence : distille 0.23 ms reste plus lent que la baseline 0.19 ms ; le gain de vitesse est contre le maître (1.24 ms), pas contre l'élève dur."
]
},
{
"cell_type": "markdown",
"id": "c36f9023",
Expand Down Expand Up @@ -258,6 +265,13 @@
" return model"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lecture du code** : La loss s'écrit `L_hard = F.cross_entropy(logits_student, y)` (terme dur) + KL tempéré : `F.kl_div(log_softmax(z_eleve/T), softmax(z_maitre/T)) * T²` (terme mou). Les deux rôles, dans la base : « à la limite `T → ∞` toutes les classes deviennent équiprobables (l'information s'efface), à `T → 1` on retombe sur la distribution dure du maître », et « le facteur `T²` compense l'amortissement du gradient des cibles molles quand `T` grandit » — facteur vérifié numériquement à la section suivante. C'est lui qui prépare la leçon de la grille de la section 5 : trop lissée (`T=5`), la cible du maître devient bruit pour l'élève."
]
},
{
"cell_type": "markdown",
"id": "14822d8f",
Expand Down Expand Up @@ -535,6 +549,13 @@
" print(f\"{a:>6.1f} {T:>4.0f} {st.mean(A):>9.4f} {st.mean(E):>9.4f}{tag}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lecture** : Verbatim : « === BASELINE student-from-scratch (1500 etiquettes, 4 graines) === », « acc = 0.8029 +/- 0.0054 ece = 0.0684 ». La grille α/T ne dit pas « supérieur partout » : meilleure case `alpha=0, T=1` (acc 0.8145, ECE 0.0458) ; mais `alpha=0, T=5` retombe à **0.7940, SOUS la baseline** (ECE 0.0934), et `alpha=0.5, T=5` à 0.8007. La base tranche elle-même : « le gain est réel mais modeste (+0.0116 en moyenne : 0.8145 contre 0.8029) » et « T=5 casse la distillation ». La distillation gagne ici en **calibration** (ECE 0.0458 contre 0.0684, ~33 % d'erreur en moins) — pas en exactitude à toute température."
]
},
{
"cell_type": "markdown",
"id": "113a9f2e",
Expand Down Expand Up @@ -728,6 +749,13 @@
"`INCONCLUSIVE` si une jambe passe et pas l’autre, `NO BEATS` si aucune ne passe.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lecture du protocole** : Verbatim : « Le verdict est `BEATS` si : (a) le gain moyen atteint au moins deux écarts-types des différences appariées, sur l'exactitude et sur la calibration ; (b) le test de Diebold–Mariano sur la perte par exemple (cross-entropie) donne un `p` médian < 0.05 » — et « Sinon on dégrade honnêtement : `INCONCLUSIVE` si une jambe passe et pas l'autre, `NO BEATS` si aucune ne passe ». Le plan est apparié : chaque paire (fold, graine) entraîne la baseline (élève dur) ET l'élève distillé (`alpha=0, T=1`) sur le même tirage de budget — la différence mesurée n'est pas entachée de variance d'échantillonnage entre les deux modèles."
]
},
{
"cell_type": "code",
"execution_count": 9,
Expand Down Expand Up @@ -930,6 +958,13 @@
"# TODO etudiant : expliquer l'effet d'une T trop grande (la cible tend vers l'uniforme)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lecture** : Verbatim : « 5 folds x 4 graines = 20 paires appariees », « exactitude : gain +0.0064 +/- 0.0113 | edge +0.6 sigma | victoires 17/20 », « calibration: gain +0.0166 +/- 0.0122 | edge +1.4 sigma | victoires 18/20 », « DM (CE/exemple): p median = 0.0000 | biais CE baseline 0.6337 vs distille 0.5813 » — et le verdict imprimé : « **VERDICT : INCONCLUSIVE** ». Le protocole du dépôt exige 2σ sur les DEUX jambes pour `BEATS` ; ici l'exactitude ne passe pas (+0.6 σ) et la calibration frôle (+1.4 σ, 18/20 victoires). Lecture honnête : la tendance favorise le distillé (le test DM sur la perte par exemple est net, p médian 0.0000), mais le notebook dégrade honnêtement en INCONCLUSIVE — la calibration est le signal le plus solide, l'exactitude reste une tendance faible."
]
},
{
"cell_type": "code",
"execution_count": 12,
Expand Down Expand Up @@ -1046,4 +1081,4 @@
},
"nbformat": 4,
"nbformat_minor": 5
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@
"print(f\"Endpoint externe : {bool(provider.base_url)}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lecture** : Verbatim : « Provider actif : openrouter », « Modele : openrouter/openai/gpt-4.1-mini », « Endpoint externe : True » — un modèle léger via passerelle pour ce lab. Le choix du modèle ne change rien à la question de la persistance de session ; seul le compte de jetons (Lab12d) en dépend."
]
},
{
"cell_type": "markdown",
"id": "9423d8a3",
Expand All @@ -101,6 +108,13 @@
"demande un **rappel** de ce contexte -- sans jamais le repeter dans la question."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le tour 1 établit le contexte métier : le dataset 'patients-2026' contient 240 lignes et 12 colonnes. L'agent répond en décrivant la structure complète du dataset. Cette première interaction est cruciale car elle pose les bases de la conversation."
]
},
{
"cell_type": "code",
"execution_count": 2,
Expand Down Expand Up @@ -132,6 +146,13 @@
"print(tour1.response_text)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lecture** : Réponse du tour 1, verbatim : « Le dataset 'patients-2026' contient 240 lignes et 12 colonnes, ce qui donne un total de 2880 cellules. Chaque colonne a en moyenne 20 valeurs distinctes. Cela suggère une diversité de données suffisante dans chaque colonne, adaptée pour des analyses statistiques ou d'apprentissage machine. » Le détail à retenir : l'agent ne recopie pas l'énoncé — il a appelé `dataset_profile` et calculé la multiplication (240 × 12 = 2880) et le profil par colonne (20 valeurs distinctes en moyenne). Le contexte posé au tour 1 est plus riche que la question : c'est ce contenu-là que le tour 2 devra retrouver."
]
},
{
"cell_type": "code",
"execution_count": 3,
Expand All @@ -158,6 +179,13 @@
"print(tour2.response_text)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le tour 2 démontre que l'agent ne conserve PAS le contexte entre appels isolés. Réponse, verbatim : « Pour répondre à cette question, j'ai besoin que tu me fournisses les dimensions (nombre de lignes et de colonnes) ou un extrait de ton dataset pour que je puisse en analyser la forme. Pourrais-tu me transmettre ces informations ? » L'agent demande à l'utilisateur de répéter ce qu'il vient de dire — le symptôme de l'absence de persistance sans ConversationRunner. Chaque appel isolé instancie une session neuve ; la question du tour 2 n'a jamais rencontré la réponse du tour 1."
]
},
{
"cell_type": "markdown",
"id": "6bf7687c",
Expand Down Expand Up @@ -226,6 +254,13 @@
"print(\" - self.session_id : identifiant stable, jamais regenere entre les tours\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lecture** : Le docstring porte les deux contrats d'une phrase : « Execute plusieurs tours d'un agent dans la MEME session ADK » (C1b) et « Le cloisonnement reste celui du contrat C1 : deux ``ConversationRunner`` sont deux sessions distinctes, isolees l'une de l'autre ». Les deux attributs imprimés font tout le travail : « self.session_service : un seul InMemorySessionService pour TOUS les tours », « self.session_id : identifiant stable, jamais regenere entre les tours ». Aucune logique propre — l'assemblage réutilise les primitives publiques d'ADK ; ce qui manquait au tour isolé de la section 2, c'était uniquement la durée de vie de ces deux objets."
]
},
{
"cell_type": "markdown",
"id": "b3a159a5",
Expand Down Expand Up @@ -279,6 +314,13 @@
"print(t3.response_text)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La classe ConversationRunner gère l’exécution de plusieurs tours d’un agent dans la MÊME session ADK persistante. Elle maintient un InMemorySessionService dédié et un session_id unique pour chaque conversation, ce qui permet à l’agent de conserver intégralement le contexte métier entre chaque tour, sans que l’utilisateur ait besoin de répéter les informations. Cette persistance de contexte est particulièrement cruciale dans les applications conversationnelles."
]
},
{
"cell_type": "markdown",
"id": "ece7500e",
Expand Down Expand Up @@ -342,6 +384,13 @@
" print(f\" {i:2d}. [{event.author or '?':>8}] <appel d'outil>\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lecture** : La chronologie imprimée montre la mécanique interne : événement 1 `[user]` (question du tour 1), événement 2 `[dataset_profile_agent]` <appel d'outil>, réponse profilée en 4 (« 240 lignes (exemples) et 12 colonnes (variables) »), question du tour 2 en 5, rappel en 6 (« Ton dataset s'appelait \"patients-2026\" »), question du tour 3 en 7, réponse calculée en 8 (« 240 × 12 = 2880 cellules »). L'événement 3 n'affiche aucun extrait (ni texte, ni appel) — le filtre d'impression ne le montre pas, mais il compte dans les 8. C'est exactement cet historique qu'ADK renvoie au LLM au tour suivant : la mémoire n'est pas dans le modèle, elle est dans cette liste."
]
},
{
"cell_type": "markdown",
"id": "05c79a6f",
Expand Down Expand Up @@ -421,6 +470,13 @@
"print(reponse_b.response_text[:300])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lecture** : La réponse de B, verbatim : « Pour vous répondre précisément, j'aurais besoin que vous me fournissiez les informations sur votre dataset, notamment le nombre de lignes et de colonnes si vous les connaissez, ou bien que vous me donniez accès à ce dataset pour analyser sa forme ». C'est le symptôme exact de l'amnésie du tour 2 isolé (section 2) — mais ici, c'est le comportement ATTENDU : B n'a jamais reçu le contexte de A, et l'isolation C1 fait qu'il ne le recevra jamais. Persistance intra-session et amnésie inter-sessions sont les deux faces de la même mécanique de session."
]
},
{
"cell_type": "markdown",
"id": "6993fe66",
Expand All @@ -435,6 +491,13 @@
"`test_c1b_conversations_still_isolate`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lecture** : Verbatim : « Evenements persistes dans la session apres 3 tours : 8 » — compteur imprimé pour la session A — puis le test croisé : « A contient 'secret-alpha' : True », « B contient 'secret-alpha' (fuite ?): False » ; la réponse de B le confirme en redemandant les informations du dataset. Persistance intra-session (8 événements accumulés sur 3 tours côté A) et isolation inter-sessions (aucune fuite du marqueur) : les deux faces du même contrat de session."
]
},
{
"cell_type": "markdown",
"id": "83af5569",
Expand Down Expand Up @@ -597,4 +660,4 @@
},
"nbformat": 4,
"nbformat_minor": 5
}
}
Loading