diff --git a/MyIA.AI.Notebooks/GenAI/Texte/09d_Production_Caches.ipynb b/MyIA.AI.Notebooks/GenAI/Texte/09d_Production_Caches.ipynb index 5065f60fca..b9a50a3957 100644 --- a/MyIA.AI.Notebooks/GenAI/Texte/09d_Production_Caches.ipynb +++ b/MyIA.AI.Notebooks/GenAI/Texte/09d_Production_Caches.ipynb @@ -1054,16 +1054,7 @@ "tags": [] }, "source": [ - "### Lecture du cache de préfixe\n", - "\n", - "Sur cette exécution, le 1ᵉʳ appel affiche déjà 88 % de tokens cachés : ce préfixe avait\n", - "déjà été envoyé quelques minutes plus tôt (runs de préparation) — le cache du fournisseur\n", - "survit d'une exécution à l'autre, c'est précisément son intérêt en production. Sur un\n", - "préfixe réellement froid, le 1ᵉʳ appel paie le plein tarif. L'économie réelle se calcule avec les **prix du catalogue** lus en section 0 : le\n", - "token caché est facturé à fraction du prix d'entrée (politique fournisseur, `R_CACHED`\n", - "ci-dessous) — on mesure la part servie, le reste est arithmétique. Le **point d'équilibre**\n", - "répond à la question qui précède tout investissement dans un préfixe long : combien d'appels\n", - "partageant ce préfixe faut-il pour que le préfixe se rentabilise ?\n" + "### Lecture du cache de préfixe\n\nSur cette exécution, le 1ᵉʳ appel affiche déjà 88 % de tokens cachés : ce préfixe avait\ndéjà été envoyé quelques minutes plus tôt (runs de préparation) — le cache du fournisseur\nsurvit d'une exécution à l'autre, c'est précisément son intérêt en production. Sur un\npréfixe réellement froid, le 1ᵉʳ appel paie le plein tarif. L'économie réelle se calcule avec les **prix du catalogue** lus en section 0 : le\ntoken caché est facturé à fraction du prix d'entrée (politique fournisseur, `R_CACHED`\nci-dessous) — on mesure la part servie, le reste est arithmétique. Le **point d'équilibre**\nrépond à la question qui précède tout investissement dans un préfixe long : combien d'appels\npartageant ce préfixe faut-il pour que le préfixe se rentabilise ?\n" ] }, { @@ -1091,31 +1082,19 @@ "name": "stdout", "output_type": "stream", "text": [ + "route tarifaire : OpenAI direct, gpt-5-mini, fiche tarifaire 2026-10-01\n", "préfixe : ~1304 tokens, part cachée mesurée sur le dernier appel : 88 %\n", "coût plein du préfixe par appel : $0.000326\n", - "économie par appel une fois chaud : $0.000144 (tarif caché = 50% du plein)\n", - "point d'équilibre : ~2 appels par préfixe pour rentrer dans les frais (au-delà, tout est gain)\n" + "économie par appel une fois chaud : $0.000259 (tarif caché = 10% du plein)\n", + "\n", + "Scénario A (préfixe commun) : chaque hit économise $0.000259 — pas d'amortissement.\n", + "Scénario B (préfixe ajouté) : requête courte = $0.000025 ; prompt long chaud = $0.000067\n", + " -> surcoût de $0.000042/appel malgré le hit — le cache fonctionne, la stratégie reste plus chère.\n" ] } ], "source": [ - "# Point d'équilibre : le préfixe coûte PRIX_IN plein tarif tant qu'il n'est pas caché ;\n", - "# une fois chaud, une part f de ses tokens est facturée au tarif réduit R_CACHED (0,5 = politique\n", - "# fournisseur standard : le token caché vaut la moitié du prix d'entrée).\n", - "R_CACHED = 0.5\n", - "tokens_prompt = mesures_pref[-1][\"prompt\"]\n", - "part_cachee = mesures_pref[-1][\"cached\"] / tokens_prompt if tokens_prompt else 0.0\n", - "cout_prefixe_usd = tokens_prompt * PRIX_IN / 1e6\n", - "economie_par_appel = tokens_prompt * (1 - R_CACHED) * part_cachee * PRIX_IN / 1e6\n", - "\n", - "print(f\"préfixe : ~{tokens_prompt} tokens, part cachée mesurée sur le dernier appel : {100 * part_cachee:.0f} %\")\n", - "print(f\"coût plein du préfixe par appel : ${cout_prefixe_usd:.6f}\")\n", - "print(f\"économie par appel une fois chaud : ${economie_par_appel:.6f} (tarif caché = {R_CACHED:.0%} du plein)\")\n", - "if economie_par_appel > 0:\n", - " n_equilibre = cout_prefixe_usd / economie_par_appel\n", - " print(f\"point d'équilibre : ~{n_equilibre:.0f} appels par préfixe pour rentrer dans les frais (au-delà, tout est gain)\")\n", - "else:\n", - " print(\"aucune économie mesurée sur ce terrain : le point d'équilibre n'existe pas\")\n" + "# Point d'équilibre : le préfixe coûte PRIX_IN plein tarif tant qu'il n'est pas caché ;\n# une fois chaud, une part de ses tokens est facturée au tarif réduit.\n# IMPORTANT (K06, #18735) : le tarif caché n'est PAS universel — il dépend du fournisseur\n# et du modèle. Pour gpt-5-mini (OpenAI, fiche tarifaire consultée le 2026-10-01),\n# l'entrée cachée est facturée à 0.1x le prix d'entrée (10 %), pas 0.5x.\n# OpenRouter n'expose pas le tarif caché dans son catalogue public : on nomme la route\n# et on cite la source. Si vous passez par un autre fournisseur, adaptez R_CACHED.\nROUTE_PRIX = \"OpenAI direct, gpt-5-mini, fiche tarifaire 2026-10-01\"\nR_CACHED = 0.1 # 10 % du plein tarif pour gpt-5-mini entrée cachée (OpenAI)\ntokens_prompt = mesures_pref[-1][\"prompt\"]\ntokens_cached = mesures_pref[-1][\"cached\"]\npart_cachee = tokens_cached / tokens_prompt if tokens_prompt else 0.0\ncout_prefixe_usd = tokens_prompt * PRIX_IN / 1e6\neconomie_par_appel = tokens_cached * (1 - R_CACHED) * PRIX_IN / 1e6\n\nprint(f\"route tarifaire : {ROUTE_PRIX}\")\nprint(f\"préfixe : ~{tokens_prompt} tokens, part cachée mesurée sur le dernier appel : {100 * part_cachee:.0f} %\")\nprint(f\"coût plein du préfixe par appel : ${cout_prefixe_usd:.6f}\")\nprint(f\"économie par appel une fois chaud : ${economie_par_appel:.6f} (tarif caché = {R_CACHED:.0%} du plein)\")\n\n# Deux scénarios de référence (K06, #18735)\n# Scénario A — préfixe commun : le même préfixe sert déjà dans les deux cas.\n# Chaque hit est une économie pure ; il n'y a pas d'investissement à amortir.\n# Le \"point d'équilibre\" n'a pas de sens ici : tout hit est un gain.\n# Scénario B — préfixe ajouté : on ajoute un long préfixe pour atteindre le cache.\n# Il faut comparer au coût de la requête courte d'origine (sans préfixe).\n# Le cache peut fonctionner ET la stratégie rester plus chère.\n# Témoin chiffré (entrée seule, PRIX_IN/M token) :\n# requête courte 100 tokens froids = 100 * PRIX_IN / 1e6\n# prompt long 1304 tokens chauds (1152 cachés) = (152 * PRIX_IN + 1152 * 0.1 * PRIX_IN) / 1e6\ncout_court = 100 * PRIX_IN / 1e6\ncout_long_chaud = ((tokens_prompt - tokens_cached) * PRIX_IN + tokens_cached * R_CACHED * PRIX_IN) / 1e6\nprint()\nprint(f\"Scénario A (préfixe commun) : chaque hit économise ${economie_par_appel:.6f} — pas d'amortissement.\")\nprint(f\"Scénario B (préfixe ajouté) : requête courte = ${cout_court:.6f} ; prompt long chaud = ${cout_long_chaud:.6f}\")\nif cout_long_chaud > cout_court:\n surcout = cout_long_chaud - cout_court\n print(f\" -> surcoût de ${surcout:.6f}/appel malgré le hit — le cache fonctionne, la stratégie reste plus chère.\")\nelse:\n print(f\" -> économie de ${cout_court - cout_long_chaud:.6f}/appel vs requête courte.\")\n" ] }, { @@ -1368,20 +1347,8 @@ "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.7" - }, - "papermill": { - "default_parameters": {}, - "duration": 182.013867, - "end_time": "2026-09-28T16:36:44.713024+00:00", - "environment_variables": {}, - "exception": null, - "input_path": "09d_Production_Caches.ipynb", - "output_path": "09d_exec.ipynb", - "parameters": {}, - "start_time": "2026-09-28T16:33:42.699157+00:00", - "version": "2.7.0" } }, "nbformat": 4, "nbformat_minor": 5 -} +} \ No newline at end of file