Wenig ändern, den Rest lassen
Ein großes Modell hat Milliarden Zahlen. Alle zu trainieren, braucht viel Speicher und Zeit. Ein Adapter, etwa ein LoRA, trainiert ein paar zusätzliche Zahlen neben den großen und lässt die großen in Ruhe.
Diese Lektion zählt diese Zahlen. Kein Labor trainiert hier ein Modell, die Arbeit ist also Rechnen, das Sie ausführen.
Am Ende dieser Lektion
Notiz
Ich kann erklären, warum ein kleiner Adapter ein großes Modell günstig verändert.
Schlüsselwörter
| Begriff | Was er bedeutet |
|---|---|
| Parameter | eine Zahl, die ein Modell gelernt hat |
| Eingefroren | beim Training nicht verändert |
| Adapter | eine kleine Menge neuer, trainierter Zahlen |
| Rang | wie dünn die zwei Adapter-Tabellen sind |
| LoRA | ein Adapter aus zwei dünnen Tabellen |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Eine Schicht ist eine Tabelle aus Zahlen
In einem Modell besteht eine Schicht großenteils aus einer Tabelle von Zahlen. Eine Tabelle mit 5 Zeilen und 4 Spalten enthält 5 mal 4, also 20 Parameter. Eine Tabelle 100 mal 100 enthält 10.000.
Volles Training ändert jede Zahl in jeder Tabelle. Darum ist es teuer.
Zwei dünne Tabellen ergeben eine große Änderung
Multiplizieren Sie eine Tabelle 5 mal 1 mit einer Tabelle 1 mal 4, erhalten Sie eine Tabelle 5 mal 4. Sie hat die Form der eingefrorenen Tabelle und lässt sich daher zu ihr addieren.
Der Adapter hält 5 plus 4, also 9 Zahlen statt 20. Der Rang ist die dünne Seite. Ein größerer Rang fasst mehr und kostet mehr.
Beispiel: eine Tabelle 80 mal 80
| Rang | Adapter-Zahlen | Anteil an den 6.400 |
|---|---|---|
| 1 | 1 x (80 + 80) = 160 | 2,5 % |
| 4 | 4 x 160 = 640 | 10 % |
| 8 | 8 x 160 = 1.280 | 20 % |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Ein häufiger Fehler
Warnung
Viele glauben, ein Adapter sei eine kleinere Kopie des Modells. Das ist er nicht. Das große Modell bleibt unverändert, und der Adapter wird zu seiner Ausgabe addiert. Nehmen Sie den Adapter weg, haben Sie das ursprüngliche Modell zurück.
Modell-Helfer schreiben, Teil 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const basis = process.env.AI_URL || \"http://ai:4000\";' '// Die Token einer Antwort oder null, wenn sie keine nennt.' 'function zaehlen(daten, name) {' ' return daten.usage && typeof daten.usage[name] === \"number\" ? daten.usage[name] : null;' '}' > model.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Modell-Helfer schreiben, Teil 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function fragen(nachrichten, probe, max) {' ' try {' ' const res = await fetch(basis + \"/v1/chat/completions\", {' ' method: \"POST\",' ' headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' ' body: JSON.stringify({ model: \"lab\", messages: nachrichten, max_tokens: max || 100 }),' ' signal: AbortSignal.timeout(30000),' ' });' ' if (res.ok === false) throw new Error(\"Status \" + res.status);' ' const d = await res.json();' ' return { text: d.choices[0].message.content, eingabe: zaehlen(d, \"prompt_tokens\"), ausgabe: zaehlen(d, \"completion_tokens\"), aufgezeichnet: false };' ' } catch (fehler) {' ' console.log(\"Aufgezeichnete Probe: Kein Modell hat geantwortet (\" + fehler.message + \").\");' ' return { text: probe, eingabe: null, ausgabe: null, aufgezeichnet: true };' ' }' '}' 'module.exports = { fragen };' >> model.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Adapter-Zähler schreiben, Teil 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { fragen } = require(\"./model\");' '// Eine eingefrorene Tabelle W mit 5 Zeilen und 4 Spalten und zwei dünne: B ist 5 mal 1, A ist 1 mal 4.' 'const zeilen = 5, spalten = 4, rang = 1;' 'const B = [2, 1, 0, 3, 1];' 'const A = [1, 0, 2, 1];' > anpassen4.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Adapter-Zähler schreiben, Teil 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function aenderung(i, j) {' ' let summe = 0;' ' for (let k = 0; k < rang; k++) summe = summe + B[i * rang + k] * A[k * spalten + j];' ' return summe;' '}' 'const voll = zeilen * spalten;' 'const adapter = rang * (zeilen + spalten);' >> anpassen4.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Adapter-Zähler schreiben, Teil 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' console.log(\"eingefrorene Tabelle: \" + zeilen + \" x \" + spalten + \" = \" + voll + \" Zahlen\");' ' console.log(\"Adapter: \" + zeilen + \" x \" + rang + \" plus \" + rang + \" x \" + spalten + \" = \" + adapter + \" Zahlen\");' ' const erste = [];' ' for (let j = 0; j < spalten; j++) erste.push(aenderung(0, j));' ' console.log(\"Änderung an Zeile 0: \" + erste.join(\" \"));' ' console.log(\"trainierter Anteil: \" + Math.floor((adapter * 100) / voll) + \" Prozent\");' ' await frageStellen();' '}' >> anpassen4.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Adapter-Zähler schreiben, Teil 4
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function frageStellen() {' ' const frage = \"Antworten Sie in einem Satz: Warum ist es günstiger, einen kleinen Adapter zu trainieren als ein ganzes Modell?\";' ' const probe = \"Nur die kleinen Adapter-Tabellen ändern sich, daher müssen weit weniger Zahlen gespeichert und angepasst werden.\";' ' const antwort = await fragen([{ role: \"user\", content: frage }], probe, 40);' ' console.log(\"Modell: \" + antwort.text);' '}' 'main();' >> anpassen4.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Adapter-Zähler ausführen
docker exec -w /home/node/project agent node anpassen4.jsHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Was der Zähler druckte
Er druckt die Größe der eingefrorenen Tabelle, die Größe des Adapters, eine Zeile der Änderung und den trainierten Anteil. Die Zahlen in A und B sind erfunden. Ein echter Adapter lernt sie.
Die letzte Zeile ist ein kurzer Modellaufruf oder eine Aufgezeichnete Probe.