Changer un peu, garder le reste
Un grand modèle a des milliards de nombres. Tous les entraîner demande beaucoup de mémoire et de temps. Un adaptateur, comme la méthode LoRA, entraîne quelques nombres de plus à côté des gros et ne touche pas aux gros.
Cette leçon compte ces nombres. Aucun labo n’entraîne de modèle : le travail est un calcul que vous lancez.
À la fin de cette leçon
Remarque
Je peux dire pourquoi un petit adaptateur change à peu de frais un grand modèle.
Mots clés
| Mot | Ce que ça veut dire |
|---|---|
| Paramètre | un nombre que le modèle a appris |
| Gelé | qui n’est pas changé pendant l’entraînement |
| Adaptateur | un petit ensemble de nombres nouveaux entraînés |
| Rang | l’épaisseur des deux tableaux de l’adaptateur |
| LoRA | un adaptateur fait de deux tableaux minces |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Une couche est un tableau de nombres
Dans un modèle, une couche est surtout un tableau de nombres. Un tableau de 6 lignes et 6 colonnes contient 6 fois 6, soit 36 paramètres. Un tableau de 100 sur 100 en contient 10 000.
L’entraînement complet change chaque nombre de chaque tableau. C’est pourquoi il coûte cher.
Deux tableaux minces font un changement complet
Multipliez un tableau de 6 sur 1 par un tableau de 1 sur 6 : vous obtenez un tableau de 6 sur 6. Il a la forme du tableau gelé, donc on peut l’y ajouter.
L’adaptateur tient 6 plus 6, soit 12 nombres, au lieu de 36. Le rang est le côté mince. Un rang plus grand contient plus et coûte plus.
Exemple : un tableau de 100 sur 100
| Rang | Nombres de l’adaptateur | Part des 10 000 |
|---|---|---|
| 1 | 1 x (100 + 100) = 200 | 2 % |
| 4 | 4 x 200 = 800 | 8 % |
| 8 | 8 x 200 = 1 600 | 16 % |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Une erreur courante
Attention
Beaucoup pensent qu’un adaptateur est une copie plus petite du modèle. Ce n’est pas le cas. Le grand modèle reste, inchangé, et l’adaptateur s’ajoute à sa sortie. Enlevez l’adaptateur et le modèle d’origine revient.
Écrire l’assistant du modèle, partie 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' '// Les jetons d’une réponse, ou null si elle n’en donne pas.' 'function compter(donnees, nom) {' ' return donnees.usage && typeof donnees.usage[nom] === \"number\" ? donnees.usage[nom] : null;' '}' > model.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire l’assistant du modèle, partie 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function demander(messages, echantillon, max) {' ' try {' ' const res = await fetch(base + \"/v1/chat/completions\", {' ' method: \"POST\",' ' headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' ' body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 100 }),' ' signal: AbortSignal.timeout(30000),' ' });' ' if (res.ok === false) throw new Error(\"statut \" + res.status);' ' const d = await res.json();' ' return { texte: d.choices[0].message.content, entree: compter(d, \"prompt_tokens\"), sortie: compter(d, \"completion_tokens\"), enregistre: false };' ' } catch (erreur) {' ' console.log(\"Échantillon enregistré : aucun modèle n’a répondu (\" + erreur.message + \").\");' ' return { texte: echantillon, entree: null, sortie: null, enregistre: true };' ' }' '}' 'module.exports = { demander };' >> model.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire le compteur d’adaptateur, partie 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' '// Un tableau gelé W de 6 sur 6, et deux tableaux minces : B fait 6 sur 1 et A fait 1 sur 6.' 'const lignes = 6, colonnes = 6, rang = 1;' 'const B = [1, 2, 0, 1, 0, 3];' 'const A = [2, 0, 1, 0, 1, 1];' > adapt4.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire le compteur d’adaptateur, partie 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function delta(i, j) {' ' let somme = 0;' ' for (let k = 0; k < rang; k++) somme = somme + B[i * rang + k] * A[k * colonnes + j];' ' return somme;' '}' 'const complet = lignes * colonnes;' 'const adaptateur = rang * (lignes + colonnes);' >> adapt4.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire le compteur d’adaptateur, partie 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' console.log(\"tableau gelé : \" + lignes + \" x \" + colonnes + \" = \" + complet + \" nombres\");' ' console.log(\"adaptateur : \" + lignes + \" x \" + rang + \" plus \" + rang + \" x \" + colonnes + \" = \" + adaptateur + \" nombres\");' ' const premiere = [];' ' for (let j = 0; j < colonnes; j++) premiere.push(delta(0, j));' ' console.log(\"changement de la ligne 0 : \" + premiere.join(\" \"));' ' console.log(\"part entraînée : \" + Math.floor((adaptateur * 100) / complet) + \" %\");' >> adapt4.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire le compteur d’adaptateur, partie 4
docker exec -w /home/node/project agent sh -c "printf '%s\n' ' const q = \"En une phrase, pourquoi entraîner un petit adaptateur coûte-t-il moins que d’entraîner tout un modèle ?\";' ' const echantillon = \"Seuls les petits tableaux de l’adaptateur changent : bien moins de nombres sont gardés et mis à jour.\";' ' const reponse = await demander([{ role: \"user\", content: q }], echantillon, 60);' ' console.log(\"le modèle dit : \" + reponse.texte);' '}' 'main();' >> adapt4.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Lancer le compteur d’adaptateur
docker exec -w /home/node/project agent node adapt4.jsAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Ce que le compteur a affiché
Il affiche la taille du tableau gelé, celle de l’adaptateur, une ligne du changement et la part entraînée. Les nombres de A et de B sont inventés. Un vrai adaptateur les apprend.
La dernière ligne est un court appel au modèle, ou un Échantillon enregistré.