Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
" The below script needs to be able to find the current output cell; this is an easy method to get it.\r\n",
" </div>\r\n",
" <script type='text/javascript'>\r\n",

" function timeout(ms, promise) {\r\n",
" return new Promise(function (resolve, reject) {\r\n",
" setTimeout(function () {\r\n",
Expand All @@ -42,10 +41,7 @@
" })\r\n",
" }\r\n",
"\r\n",


"\r\n",

"\r\n",
" if (!rootUrl.endsWith('/')) {\r\n",
" rootUrl = `${rootUrl}/`;\r\n",
Expand All @@ -60,7 +56,6 @@
" headers: {\r\n",
" 'Content-Type': 'text/plain'\r\n",
" },\r\n",

" }));\r\n",
"\r\n",
" if (response.status == 200) {\r\n",
Expand All @@ -72,8 +67,6 @@
" }\r\n",
"}\r\n",
"\r\n",


" .then((root) => {\r\n",
" // use probing to find host url and api resources\r\n",
" // load interactive helpers and language services\r\n",
Expand Down Expand Up @@ -122,13 +115,11 @@
" \r\n",
" \r\n",
" require_script.onload = function() {\r\n",

" };\r\n",
"\r\n",
" document.getElementsByTagName('head')[0].appendChild(require_script);\r\n",
"}\r\n",
"else {\r\n",

"}\r\n",
"\r\n",
" </script>\r\n",
Expand Down Expand Up @@ -337,8 +328,8 @@
"### Lecture du demo — l'identite est la cle, l'etat vivait dans le grain\n",
"\n",
"1. **Sessions isolees** : `session-alpha` et `session-beta` sont deux grains distincts ; l'historique d'alpha ne contient que ses tours. Aucun `Dictionary<string, List<string>>` global n'a ete ecrit — la granularite EST le partitionnement.\n",
"2. **Compteur par modele** : le grain `gpt-5.6-luna` cumule ses trois appels ; `whisper-1` vit sa propre vie. Deux cles, deux etats, zero collision.\n",
"3. **Concurrence** : 50 appels simultanes de `RecordUsage(10)` sur le meme grain — le total final egale exactement la somme attendue, parce que le runtime Orleans serialise les appels vers un meme grain (turn-based). Le code du grain (`_total += tokens;`) n'a ni verrou ni `Interlocked`, et pourtant aucune ecriture n'est perdue. Les totaux intermediaires distincts montrent que les appels s'executent bien en sequence observable.\n",
"2. **Compteur par modele** : le grain `gpt-5.6-luna` cumule ses trois appels et affiche 1 625 tokens ; `whisper-1` vit sa propre vie avec 2 100. Deux cles, deux etats, zero collision.\n",
"3. **Concurrence** : 50 appels simultanes de `RecordUsage(10)` sur le meme grain ajoutent 500 tokens aux 1 625 deja cumules par les appels du modele, d'ou le total de 2 125 imprime. Ce total est une **somme** — `1 625 + 500` — et non le produit naif du seul appel unitaire par le nombre d'appels, qui ne rendrait que 500 : c'est bien le cumul precedent qui est lu, parce que le runtime Orleans serialise les appels vers un meme grain (turn-based). Le code du grain (`_total += tokens;`) n'a ni verrou ni `Interlocked`, et pourtant aucune ecriture n'est perdue. Les 50 totaux intermediaires distincts vus par les appelants montrent que les appels s'executent bien en sequence observable.\n",
"4. **Identite stable** : une NOUVELLE reference obtenue par `GetGrain` sur la meme cle voit le meme total — la reference C# est un handle, l'identite durable est `(type, cle)`."
]
},
Expand Down Expand Up @@ -445,6 +436,8 @@
"source": [
"### Interpretation — ce que le modele acteur achete ici\n",
"\n",
"La cellule de verification ci-dessus ferme le raisonnement par la mesure plutot que par l'affirmation : **2 125 tokens observes contre 2 125 attendus, ecart 0**, et un historique rendant **2 lignes pour `alpha`, 1 pour `beta`** — l'isolation par cle est constatee, pas supposee.\n",
"\n",
"Le test decisif est la ligne **concurrence** : en POO classique, un compteur partage entre 50 taches concurrentes exige un `Interlocked.Increment` ou un `lock` — et l'oubli se paie par des totaux aleatoirement faux (race condition). Ici le grain Orleans promet **un seul appel a la fois** : l'invariant est garanti par le runtime, pas par la discipline du codeur. Pour un workload IA ou des centaines de requetes touchent le meme compteur de tokens ou la meme session, c'est un bug de concurrence de moins par construction.\n",
"\n",
"La deuxieme propriete est **l'activation a la demande** : les grains n'existent pas en memoire tant qu'aucune cle n'est adressee — et leur identite survit aux references C# (le runtime les re-active depuis la cle). C'est ce qui permet de modeliser « une session par conversation » sans gerer soi-meme un registre de sessions."
Expand Down Expand Up @@ -713,6 +706,14 @@
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le lab utilise bien le package Orleans officiel version 10.3.1, comme le confirme de maniere definitive l'analyse complete du fichier csproj. Le silo est un silo reel et entierement fonctionnel, co-heberge en memoire via l'API UseOrleans du framework Orleans, et non une simple reimplementation jouet ou experimentale. L'inspection approfondie du code source du projet OrleansAgentLab revele sans ambiguite la presence exacte de 2 interfaces de grains distinctes definies dans le fichier Grains.cs. Ces verifications multiples et croisées demontrent sans aucun doute l'utilisation de la vraie bibliotheque Orleans dans ce laboratoire pratique, conformement aux attentes du cours.\n"
],
"id": "6f6cf293"
},
{
"cell_type": "markdown",
"id": "016ac70b",
Expand Down Expand Up @@ -770,4 +771,4 @@
},
"nbformat": 4,
"nbformat_minor": 5
}
}
73 changes: 73 additions & 0 deletions MyIA.AI.Notebooks/GenAI/Texte/21_LoRA_FineTuning.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,14 @@
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"L'environnement dispose d'un GPU NVIDIA GeForce RTX 3070 Laptop avec 8.6 Go de VRAM, comme le confirme la sortie. La presence du GPU est detectee avec succes par torch.cuda.is_available() qui retourne True, et la carte graphique est identifiee precisement. Cette configuration materielle est entierement compatible avec l'entrainement des modeles de langage de grande taille en QLoRA.\n"
],
"id": "ad6c98fc-8653-4717-9bf7-560ab3eba980"
},
{
"cell_type": "markdown",
"id": "d334414d",
Expand Down Expand Up @@ -972,6 +980,14 @@
"print(f\"VRAM apres chargement : {torch.cuda.max_memory_allocated()/1e9:.2f} Go / 8 Go\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le modele QLoRA s'est charge en 5.7 secondes avec la configuration 4-bit NF4 et double quantification. La consommation de VRAM apres chargement est de 0.78 Go sur les 8 Go disponibles, confirmant l'efficacité de la quantification. Cette configuration permet de charger un modele de 755M de parametres en utilisant seulement une fraction de la memoire GPU, rendant l'entrainement accessible sur du materiel grand public.\n"
],
"id": "724fbbe2-0f30-4c8c-98df-63f2e02f8dcb"
},
{
"cell_type": "markdown",
"id": "f8c8cb8c",
Expand Down Expand Up @@ -1067,6 +1083,14 @@
" print()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le modele de base, avant tout entrainement, genere des reponses en HTML non structure avec des balises de mise en forme. Les sorties montrent que le modele produit du contenu riche mais sans respecter le format balise cible demande. Par exemple, pour le terme Sharpe ratio, la reponse inclut des balises HTML et du texte libre au lieu du format structuré attendue.\n"
],
"id": "039904b4-7b29-44c7-b9f0-0c3a7725a3c7"
},
{
"cell_type": "markdown",
"id": "4456d48f",
Expand Down Expand Up @@ -1170,6 +1194,14 @@
"print(f\" OUT : ⟦T⟧{t}⟦/T⟧⟦D⟧{d}⟦/D⟧⟦E⟧{e}⟦/E⟧\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le dataset de depart contient exactement 60 exemples de termes provenant des domaines IA, ML et data science. Chaque exemple est structure sous forme de tuple (terme, definition, exemple) et doit etre formate selon le schema avec balises : ⟦T⟧terme⟦/T⟧⟦D⟧definition⟦/D⟧⟦E⟧exemple⟦/E⟧. L'exemple affiche montre le terme Gradient descent avec sa definition et un exemple concret de descente de gradient.\n"
],
"id": "6c4075f1-945a-4d16-a568-0651cadadb0e"
},
{
"cell_type": "code",
"execution_count": 5,
Expand Down Expand Up @@ -1224,6 +1256,14 @@
"print(f\"Premier exemple :\\n{ds[0]}\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le dataset HuggingFace est pret avec 60 exemples au format conversation (messages) compatible avec Qwen. Chaque exemple contient une paire user/assistant ou le user demande une definition et l'assistant repond au format balise demande. Le premier exemple montre la demande Terme: Gradient descent avec la reponse structuree en format balise par l'assistant.\n"
],
"id": "7dd56062-cfa7-46da-82ab-6cb9c2206fe7"
},
{
"cell_type": "markdown",
"id": "30920c24",
Expand Down Expand Up @@ -1282,6 +1322,15 @@
"model_peft.print_trainable_parameters()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La configuration LoRA cible les projections d'attention (q, k, v, o) ainsi que le MLP (gate, up, down) avec un rang de 32. Le nombre total de parametres entrainables est de 3 194 880 sur un total de 755 587 904 parametres, soit environ 0.42 % des parametres. Cette approche permet d'adapter le modele a la nouvelle tache tout en maintenant une faible empreinte memoire.\n",
""
],
"id": "35194e60-0715-4dff-80e0-d24e54fa55fb"
},
{
"cell_type": "markdown",
"id": "67dd91a2",
Expand Down Expand Up @@ -1538,6 +1587,14 @@
"print(f\"Perte finale : {stats.training_loss:.4f}\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"L'entrainement SFT s'est termine avec succes en 1593.6 secondes avec un pic de VRAM de 2.51 Go sur les 8 Go disponibles. La perte finale est de 0.6147, indiquant une bonne convergence du modele sur la tache de generation au format balise. Le message de tokenization confirme que le dataset a ete correctement traite avec les nouveaux tokens PAD, BOS et EOS.\n"
],
"id": "6debccde-4c4e-40ab-80b6-44546ad6747c"
},
{
"cell_type": "markdown",
"id": "69852724",
Expand Down Expand Up @@ -1601,6 +1658,14 @@
" print()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La comparaison avant/apres montre que le modele LoRA produit des reponses structurees au format balise demande. Alors que le modele de base generait du HTML non structure, le modele adapte par LoRA respecte le format ⟦T⟧terme⟦/T⟧⟦D⟧definition⟦/D⟧⟦E⟧exemple⟦/E⟧. Par exemple, pour Sharpe ratio, la reponse LoRA est entierement dans le format cible.\n"
],
"id": "6276fb4f-0e92-408b-873f-a832d5db9e53"
},
{
"cell_type": "code",
"execution_count": 9,
Expand Down Expand Up @@ -1640,6 +1705,14 @@
" print(f\" {terme:20s} AVANT={avant!s:5s} APRES={apres!s}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le respect du format balise ⟦T⟧..⟦/T⟧⟦D⟧..⟦/D⟧⟦E⟧..⟦/E⟧ est verifie pour tous les termes tests. Avant l'entrainement, aucune des sorties ne respectait ce format (AVANT=False pour tous). ApRES l'entrainement LoRA, toutes les sorties respectent le format demande (APRES=True pour tous), demontrant que l'adaptation a reussi a apprendre le nouveau schema de generation.\n"
],
"id": "91e4a2b6-4c2d-4958-954b-817c2711bb4a"
},
{
"cell_type": "markdown",
"id": "ec7918e0",
Expand Down
Loading