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
110 changes: 110 additions & 0 deletions MyIA.AI.Notebooks/GenAI/Texte/16_Scaling_Test_Time_Compute.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,27 @@
"print(\"Ping :\", repr(_ping[:40]) if _ping else \"ECHEC\")"
]
},
{
"cell_type": "markdown",
"id": "5a397b68",
"metadata": {},
"source": [
"### Lecture : le wrapper `chat()` — connectivity prouvée, échec toléré\n",
"\n",
"Le `Ping : '!!!!!!!!!!'` établit la seule chose qu'on doit savoir avant toute\n",
"expérience : la route vers le modèle (via OpenRouter) répond. Le wrapper\n",
"mérite une lecture attentive car TOUT le notebook repose sur lui : `retries=2`\n",
"avec repli silencieux — une requête transitoire ne tue pas une collecte\n",
"d'échantillons — et la fonction renvoie `''` en cas d'échec total plutôt que\n",
"de lever. Ce choix de robustesse a une contrepartie méthodologique : un\n",
"échec persistant se traduit par une réponse VIDE comptée comme incorrecte\n",
"dans les estimateurs qui suivent, pas par un crash visible — les taux mesurés\n",
"sont donc des bornes inférieures en présence d'erreurs réseau. Noter aussi le\n",
"`temperature=0.7` par défaut : c'est lui qui fournit la diversité\n",
"d'échantillonnage dont Best-of-N a besoin — à température 0, six échantillons\n",
"d'un même prompt seraient six clones et le pass@k n'aurait plus de sens."
]
},
{
"cell_type": "markdown",
"id": "9e71d685",
Expand Down Expand Up @@ -298,6 +319,28 @@
"print(\"pass@k (n=6, c=4):\", {k: round(pass_at_k(6, 4, k), 3) for k in (1, 2, 4, 6)})"
]
},
{
"cell_type": "markdown",
"id": "58917aa8",
"metadata": {},
"source": [
"### Lecture : l'estimateur non-biaisé pass@k — la formule se vérifie sur la sortie\n",
"\n",
"La sortie `pass@k (n=6, c=4): {1: 0.667, 2: 0.933, 4: 1.0, 6: 1.0}` se\n",
"recompute à la main, et c'est l'occasion de comprendre CE que mesure\n",
"l'estimateur. Sur `n = 6` échantillons dont `c = 4` corrects, pass@k est la\n",
"probabilité qu'un sous-ensemble ALÉATOIRE de k réponses contienne au moins\n",
"une correcte : `pass@k = 1 - C(n-c, k) / C(n, k)`. Vérification sur les\n",
"nombres affichés : pass@1 = 1 - C(2,1)/C(6,1) = 1 - 2/6 = `0,667` ;\n",
"pass@2 = 1 - C(2,2)/C(6,2) = 1 - 1/15 = `0,933` ; pass@4 = 1 - C(2,4)/C(6,4)\n",
"= 1 - 0 = `1,0` — choisir 4 réponses sur 6 quand 2 seulement sont fausses\n",
"garantit une correcte. L'intérêt de la forme binomiale (Chen 2021, reprise\n",
"par Snell 2024) : elle est NON-BIAISÉE sans exiger le partitionnement en k\n",
"groupes disjoints, et chaque tirage de n échantillons alimente TOUS les k\n",
"simultanément — exactement ce que la suite exploite pour tracer les courbes\n",
"de scaling à coût constant."
]
},
{
"cell_type": "markdown",
"id": "5ef441ab",
Expand Down Expand Up @@ -405,6 +448,27 @@
" print(f\"{b:11s} | \" + \" | \".join(f\" {agg[b][k]:.2f} \" for k in K_LIST))"
]
},
{
"cell_type": "markdown",
"id": "2dceaed1",
"metadata": {},
"source": [
"### Lecture : une seule ligne scale — le résultat central de Snell en un tableau\n",
"\n",
"Le tableau condense l'expérience BoN (`6` échantillons par problème,\n",
"`meta-llama/llama-3.3-70b-instruct`) et sa lecture tient en une asymétrie :\n",
"les buckets `facile` et `moyen` affichent `1,00` sur TOUTE la ligne —\n",
"saturés dès pass@1, aucun k ne les améliore — tandis que `difficile` passe\n",
"de `0,25` à `0,50` entre k=1 et k=4. C'est LE résultat de Snell 2024 rendu\n",
"visible : le bénéfice du test-time compute dépend du RÉGIME du problème.\n",
"Sur un problème que le modèle résout déjà, dépenser plus d'échantillons est\n",
"du gaspillage ; sur un problème à la frontière de sa capacité, doubler les\n",
"tentatives double quasi le taux. Conséquence pratique directe : un budget\n",
"d'inférence s'alloue par difficulté estimée, pas uniformément — c'est ce que\n",
"la section 3 formalise en opposant parallèle (BoN) et séquentiel\n",
"(Reflexion) à budget égal."
]
},
{
"cell_type": "code",
"execution_count": 5,
Expand Down Expand Up @@ -470,6 +534,28 @@
"print(\"c'est le resultat central de Snell : le gain du scaling depend du regime.\")"
]
},
{
"cell_type": "markdown",
"id": "3041423d",
"metadata": {},
"source": [
"### Lecture : la figure traduit le tableau — plateaux contre pentes\n",
"\n",
"La Figure 1 porte en abscisse le k et en ordonnée le pass@k, une courbe par\n",
"bucket. Les deux tables précédentes annoncent les formes : `facile` et\n",
"`moyen` dessinent des lignes PLATES au plafond (la saturation est immédiate,\n",
"la courbe ne raconte rien), `difficile` une PENTE qui monte de 0,25 vers\n",
"0,50 — c'est la courbe qui porte l'information, et elle monte exactement\n",
"comme le prédit le régime « la capacité augmente avec le budget ». La\n",
"légende imprimée sous la figure formule le critère de lecture : si facile\n",
"sature vite et difficile monte avec k, le gain du scaling dépend du régime.\n",
"Un détail de méthode : les points proviennent du MÊME tirage de 6\n",
"échantillons (l'estimateur binomial réutilise chaque tirage pour tous les\n",
"k), ce qui rend les courbes cohérentes entre elles — mais avec un seul\n",
"tirage par problème, la pente de `difficile` reste une estimation à petit\n",
"n : la section 4 y reviendra honnêtement."
]
},
{
"cell_type": "markdown",
"id": "4baf4295",
Expand Down Expand Up @@ -593,6 +679,30 @@
" print(f\"{b:11s} | {bon:.2f} | {ref:.2f} <- {gagnant}\")"
]
},
{
"cell_type": "markdown",
"id": "2a8e00d5",
"metadata": {},
"source": [
"### Lecture : « égal » partout — la frontière compute-optimale NON tranchée à cette échelle\n",
"\n",
"Le tableau final compare, à budget de calcul ÉGAL (4 appels), le parallèle\n",
"(BoN pass@4) et le séquentiel (Reflexion K=4) : `1,00 / 1,00`, `1,00 /\n",
"1,00`, `0,50 / 0,50` — et les annotations `<- egal` assumées par le\n",
"notebook. Sur CE déploiement, CE modèle et CES problèmes, la frontière de\n",
"Snell (Reflexion gagne en difficile, BoN en facile) n'apparaît pas : les\n",
"régimes saturés ne pouvaient pas départager les stratégies (plafond\n",
"commun), et le bucket difficile aboutit à l'égalité parfaite. Une lecture\n",
"naïve y verrait un échec ; c'est au contraire l'exemple type de la\n",
"différence entre résultat ILLUSTRATIF et conclusion statistique — avec 3\n",
"problèmes par bucket et un seul tirage, l'expérience n'a tout simplement pas\n",
"la puissance pour trancher, et le notebook le dit (section 4, limites). La\n",
"leçon méthodologique vaut plus que la figure : à budget égal, aucune des\n",
"deux stratégies ne domine universellement, et départager parallèle et\n",
"séquentiel exige des n plus grands et des problèmes plus discriminants —\n",
"exactement l'objet des exercices 1 et 3."
]
},
{
"cell_type": "code",
"execution_count": 7,
Expand Down
99 changes: 99 additions & 0 deletions MyIA.AI.Notebooks/GenAI/Texte/20_OWUI_Native_API.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,28 @@
" return 0, {\"_url_error\": str(e.reason)}"
]
},
{
"cell_type": "markdown",
"id": "d1fd2a98",
"metadata": {},
"source": [
"### Lecture : le contrat d'accès déclaré dès la première cellule\n",
"\n",
"La sortie énonce les deux faits qui conditionnent tout le notebook :\n",
"`Tenant : https://open-webui.myia.io` — la cible est l'instance de production\n",
"— et `Cle API : (ABSENTE -> couche auth RECOVERABLE-MACHINE)`. Deux\n",
"disciplines se lisent dans ces deux lignes. D'abord l'ordre de lecture\n",
"env-first : l'URL vient de l'environnement (`os.getenv`), la clé aussi — sans\n",
"LITTÉRAL de secours, conformément à l'hygiène secrets : une clé absente est\n",
"un état dégradé AFFICHÉ, jamais une valeur par défaut codée en dur. Ensuite\n",
"l'honnêteté anticipée : le notebook déclare AVANT toute requête que sa\n",
"couche authentifiée s'exécutera en mode RECOVERABLE-MACHINE si la clé\n",
"manque — chaque cellule concernée portera ce verdict plutôt qu'une sortie\n",
"fabriquée. La suite du notebook est donc lisible des deux façons : avec la\n",
"clé, chaque route rend sa vraie réponse ; sans elle, la FRONTIÈRE entre ce\n",
"qui s'exécute et ce qui se dégrade reste visible cellule par cellule."
]
},
{
"cell_type": "markdown",
"id": "pub-md",
Expand Down Expand Up @@ -136,6 +158,28 @@
"print(json.dumps(payload, indent=2, ensure_ascii=False))"
]
},
{
"cell_type": "markdown",
"id": "2cffd104",
"metadata": {},
"source": [
"### Lecture : `/health` — la sonde de vie, et rien d'autre\n",
"\n",
"`GET /health -> HTTP 200` avec pour corps entier `{\"status\": true}` : c'est\n",
"la réponse la plus pauvre du notebook, et c'est précisément ce qui en fait\n",
"une sonde. La sémantique d'une route de santé est la LIVENESS : le processus\n",
"répond, la boucle HTTP est vivante — rien de plus. Elle ne dit rien de la\n",
"version (cellule suivante), rien des fonctionnalités activées (`/api/config`\n",
"ensuite), rien de l'état des dépendances (base de données, moteur\n",
"d'inférence) : un service peut être « healthy » au sens de cette route et\n",
"fonctionnellement dégradé. C'est pourquoi les clients sérieux sonnent\n",
"`/health` à haute fréquence et à bas coût (une réponse d'un objet), et\n",
"réservent les routes riches — version, config — aux démarrages et aux\n",
"diagnostics. Pour l'exercice 2 du notebook, qui construit une sonde\n",
"multi-tenant, cette hiérarchie est le point de départ : mesurer la vie\n",
"d'abord, décrire le service ensuite."
]
},
{
"cell_type": "code",
"execution_count": 3,
Expand Down Expand Up @@ -169,6 +213,29 @@
"print(json.dumps(payload, indent=2, ensure_ascii=False))"
]
},
{
"cell_type": "markdown",
"id": "4cb42d45",
"metadata": {},
"source": [
"### Lecture : `/api/version` — la version comme contrat, `deployment_id` comme identité vide\n",
"\n",
"`{\"version\": \"0.9.6\", \"deployment_id\": \"\"}` tient en deux champs et se lit\n",
"comme un contrat de compatibilité. La `version` EXACTE est ce sur quoi un\n",
"client peut épingler ses attentes : les routes `/api/v1/*` de la section 2,\n",
"les automations et tools de la section 3 ont une surface qui évolue de\n",
"`0.9.x` en `0.9.x`, et un intégrateur qui teste contre `0.9.6` sait que son\n",
"code ne dépend pas d'un comportement d'une autre version. Le\n",
"`deployment_id` VIDE est tout aussi instructif : c'est l'identifiant\n",
"optionnel qu'un opérateur peut positionner pour distinguer deux instances\n",
"de la même version (canari contre production, par exemple) — sa valeur\n",
"nulle ici dit que ce tenant ne s'est pas enregistré d'identité propre, et\n",
"qu'en contexte multi-tenant (l'exercice 2), la version seule ne suffira\n",
"PAS à distinguer deux déploiements : il faudra la croiser avec l'URL du\n",
"tenant. Deux champs, deux usages : la version regarde la compatibilité,\n",
"l'identité regarde l'exploitation."
]
},
{
"cell_type": "code",
"execution_count": 4,
Expand Down Expand Up @@ -283,6 +350,38 @@
"print(json.dumps(payload, indent=2, ensure_ascii=False))"
]
},
{
"cell_type": "markdown",
"id": "4a66a1bf",
"metadata": {},
"source": [
"### Lecture : le 401 — la frontière rendue visible en une requête\n",
"\n",
"`GET /api/v1/models (sans token) -> HTTP 401` avec le corps enveloppé\n",
"`{\"_http_error\": 401, \"_body\": \"{\"detail\":\"Not authenticated\"}\"}` : cette\n",
"cellule est la démonstration expérimentale de la frontière annoncée par la\n",
"section précédente. Même route, même verbe, même client — seule différence\n",
"avec la cellule suivante : l'en-tête `Authorization: Bearer ...` absent. Le\n",
"serveur répond 401 Unauthorized, dont la sémantique exacte est « identité\n",
"MANQUANTE ou invalide » — à distinguer de 403 Forbidden, « identité connue\n",
"mais droits insuffisants » : la première se règle en présentant un jeton, la\n",
"seconde en changeant de rôle. Deux autres lectures utiles dans ce corps :\n",
"le message `Not authenticated` vient du serveur (FastAPI) et confirme que\n",
"la protection est au niveau du FRAMEWORK, pas d'un proxy périphérique ; et\n",
"l'enveloppe `_http_error` / `_body` est le pattern d'encapsulation du\n",
"helper `http_get` du notebook — les erreurs ne lèvent pas, elles SE\n",
"RENDENT, pour qu'une route protégée se lise comme une donnée parmi les\n",
"autres. C'est exactement ce qui permet à la cellule suivante de comparer\n",
"sans et avec jeton en gardant le même format de sortie. Pour mémoire, la\n",
"famille complète des codes d'erreur applicatifs se lit comme un arbre de\n",
"décision : 401 — présente ton identité ; 403 — ton identité ne suffit pas ;\n",
"404 — la route elle-même n'existe pas (à ne pas confondre avec 401 sur une\n",
"route protégée, que certains serveurs renvoient justement POUR masquer\n",
"l'existence de la route) ; 5xx — le problème est côté serveur. Savoir\n",
"lequel des quatre on reçoit, c'est savoir quel acteur peut le corriger :\n",
"l'appelant, l'administrateur des droits, ou personne."
]
},
{
"cell_type": "code",
"execution_count": 6,
Expand Down
Loading