<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Local AI on kenji.blog</title><link>http://kenji.blog/de/tags/local-ai/</link><description>Recent content in Local AI on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>de</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 16:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/de/tags/local-ai/index.xml" rel="self" type="application/rss+xml"/><item><title>Wie man TinyLLaMA in einer On-Premises-Umgebung am schnellsten feinabstimmt</title><link>http://kenji.blog/de/p/tinyllama-on-premises-fast-tuning-guide/</link><pubDate>Fri, 11 Sep 2026 16:00:00 +0900</pubDate><guid>http://kenji.blog/de/p/tinyllama-on-premises-fast-tuning-guide/</guid><description>&lt;img src="http://kenji.blog/p/tinyllama-on-premises-fast-tuning-guide/img/eyecatch.jpg" alt="Featured image of post Wie man TinyLLaMA in einer On-Premises-Umgebung am schnellsten feinabstimmt" />&lt;h2 id="1-einführung-warum-gerade-jetzt-tinyllama-und-on-premises">1. Einführung: Warum gerade jetzt TinyLLaMA und On-Premises?
&lt;/h2>&lt;p>Die Entwicklung von Large Language Models (LLM) schreitet mit enormer Geschwindigkeit voran, und dementsprechend wächst auch die Anzahl der Modellparameter stetig in die Hunderte von Milliarden. Während gigantische Modelle wie GPT-4 und Claude 3 eine beispiellose Leistung aufweisen, stellen die Rechenkosten für Inferenz und Training sowie Sicherheits- und Datenschutzbedenken bei der Nutzung externer APIs große Hürden für Unternehmen dar. Insbesondere in Geschäftsbereichen, die mit hochsensiblen internen Daten oder persönlichen Informationen umgehen, ist das Senden von Daten an öffentliche LLM-APIs in der Cloud aus Compliance-Gründen (wie DSGVO oder APPI) oft nicht zulässig.&lt;/p>
&lt;p>Daher rücken &lt;strong>Small Language Models (SLM)&lt;/strong> und der &lt;strong>lokale Betrieb in On-Premises-Umgebungen&lt;/strong> ins Rampenlicht. Unter diesen zeichnet sich &amp;ldquo;&lt;strong>TinyLLaMA&lt;/strong>&amp;rdquo; durch seine kompakte Größe von nur 1,1B (1,1 Milliarden) Parametern aus, während es mit einem riesigen Datensatz von etwa 3 Billionen Token vortrainiert wurde. Es zeigt im Vergleich zu Modellen derselben Klasse eine erstaunliche Leistung.&lt;/p>
&lt;p>Dieser Artikel bietet einen vollständigen Leitfaden, wie Sie TinyLLaMA in einer On-Premises-Umgebung (lokaler Server oder Workstation) &amp;ldquo;am schnellsten und effizientesten&amp;rdquo; für Ihre eigenen spezifischen Aufgaben feinabstimmen (Fine-Tuning) können. Wir werden alles umfassend abdecken, von den mathematischen Grundlagen über die neuesten Optimierungstechnologien bis hin zum konkreten PyTorch-Implementierungscode.&lt;/p>
&lt;hr>
&lt;h2 id="2-architektur-und-eigenschaften-von-tinyllama">2. Architektur und Eigenschaften von TinyLLaMA
&lt;/h2>&lt;p>TinyLLaMA folgt der von Meta entwickelten LLaMA (Large Language Model Meta AI)-Architektur. Obwohl die Anzahl der Parameter auf 1,1B begrenzt ist, verwendet es denselben Technologie-Stack wie LLaMA 2, was zu einer extrem hohen Ökosystem-Kompatibilität führt.&lt;/p>
&lt;h3 id="hauptkomponenten-der-architektur">Hauptkomponenten der Architektur
&lt;/h3>&lt;ol>
&lt;li>&lt;strong>RMSNorm (Root Mean Square Normalization):&lt;/strong>
Eine Normalisierungsmethode, die die Subtraktion des Mittelwerts aus der herkömmlichen LayerNorm-Berechnung weglässt und so die Recheneffizienz verbessert. Sie erhöht den Durchsatz, während die Stabilität des Trainings erhalten bleibt.&lt;/li>
&lt;li>&lt;strong>SwiGLU-Aktivierungsfunktion:&lt;/strong>
Im Feed Forward Network (FFN) wird SwiGLU anstelle von herkömmlichem ReLU oder GELU verwendet. Dies wird mathematisch wie folgt ausgedrückt:
$$ \text{SwiGLU}(x, W, V) = \text{Swish}(xW) \otimes (xV) $$
Hierbei steht $\otimes$ für das elementweise Produkt (Hadamard-Produkt) und die Swish-Funktion ist $\text{Swish}(z) = z \cdot \sigma(\beta z)$. Dadurch wird die Ausdruckskraft deutlich erhöht.&lt;/li>
&lt;li>&lt;strong>RoPE (Rotary Position Embedding):&lt;/strong>
Eine Methode, die die Vorteile von absoluter und relativer Positionskodierung kombiniert. Sie bietet eine hohe Generalisierungsleistung, auch wenn die Sequenzlänge erweitert wird.&lt;/li>
&lt;li>&lt;strong>Grouped Query Attention (GQA):&lt;/strong>
Ein Ansatz, der zwischen Multi-Head Attention (MHA) und Multi-Query Attention (MQA) liegt. Durch die Gruppierung von Key- und Value-Heads wird Speicherbandbreite gespart und die Inferenzgeschwindigkeit drastisch verbessert.&lt;/li>
&lt;/ol>
&lt;p>Das folgende Mermaid-Diagramm zeigt den allgemeinen Datenfluss und die Struktur der Transformer-Blöcke von TinyLLaMA.&lt;/p>
&lt;div class="mermaid">graph TD
A["Eingabetext"] --> B["Tokenizer (BPE)"]
B --> C["Embedding-Schicht"]
C --> D["Transformer-Blöcke (x22 Schichten für TinyLLaMA)"]
D --> E["RMSNorm (Final)"]
E --> F["Lineare Projektion (Vokabulargröße)"]
F --> G["Ausgabewahrscheinlichkeiten (Softmax)"]
subgraph "Aufbau des Transformer-Blocks"
D1["Eingabe Hidden State"] --> D2["RMSNorm"]
D2 --> D3["Grouped Query Attention (GQA)"]
D3 --> D4["Residuales Hinzufügen"]
D4 --> D5["RMSNorm"]
D5 --> D6["SwiGLU FFN"]
D6 --> D7["Residuales Hinzufügen"]
D7 --> D8["Ausgabe zur nächsten Schicht"]
D1 -.-> D4
D4 -.-> D7
end&lt;/div>
&lt;hr>
&lt;h2 id="3-durchbruch-beim-fine-tuning-lora-und-qlora">3. Durchbruch beim Fine-Tuning: LoRA und QLoRA
&lt;/h2>&lt;p>Die Feinabstimmung aller Parameter in einer On-Premises-Umgebung würde selbst für ein 1,1B-Modell Dutzende Gigabyte an VRAM (Videospeicher) verbrauchen, um die Optimizer-Zustände und Gradienten zu speichern. Um mit begrenzten Ressourcen effizient trainieren zu können, ist der Einsatz von &lt;strong>PEFT (Parameter-Efficient Fine-Tuning)&lt;/strong>-Methoden wie &amp;ldquo;&lt;strong>LoRA&lt;/strong>&amp;rdquo; und dessen quantisierter Erweiterung &amp;ldquo;&lt;strong>QLoRA&lt;/strong>&amp;rdquo; unerlässlich.&lt;/p>
&lt;h3 id="31-mathematischer-hintergrund-von-lora-low-rank-adaptation">3.1 Mathematischer Hintergrund von LoRA (Low-Rank Adaptation)
&lt;/h3>&lt;p>LoRA ist eine Methode, bei der die vortrainierte Gewichtsmatrix fixiert (eingefroren) wird und der Aktualisierungsbetrag dieser Gewichte ($\Delta W$) durch das Produkt von zwei kleinen Matrizen mit niedrigem Rang (Low-Rank) angenähert wird.&lt;/p>
&lt;p>Sei das vortrainierte Gewicht $W_0 \in \mathbb{R}^{d \times k}$. Beim vollständigen Fine-Tuning wird $W_0$ selbst aktualisiert zu $W_0 + \Delta W$, aber bei LoRA wird die Aktualisierungsmatrix $\Delta W$ wie folgt zerlegt:&lt;/p>
$$ \Delta W = B \times A $$
&lt;p>Hierbei sind $B \in \mathbb{R}^{d \times r}$ und $A \in \mathbb{R}^{r \times k}$, und $r$ ist ein Hyperparameter namens Rang (Rank), der ein sehr kleiner Wert ist (typischerweise 8, 16, 32 usw.), der $r \ll \min(d, k)$ erfüllt.&lt;/p>
&lt;p>Die Berechnung des Vorwärtsdurchlaufs (Forward Pass) sieht wie folgt aus:&lt;/p>
$$ h = W_0 x + \Delta W x = W_0 x + B A x $$
&lt;p>Im Initialzustand wird die Matrix $A$ zufällig mit einer Normalverteilung (Gauß-Verteilung) initialisiert, und die Matrix $B$ wird als Nullmatrix initialisiert. Dadurch ist $\Delta W$ zu Beginn des Trainings null, sodass das Training in einem Zustand gestartet werden kann, in dem die Ausgabe des Basismodells vollständig erhalten bleibt.&lt;/p>
&lt;div class="mermaid">graph LR
X["Eingabevektor x"] --> W0["Eingefrorenes vortrainiertes Gewicht (W_0)"]
X --> A["Trainierbare LoRA-Matrix A (r x k)"]
A --> B["Trainierbare LoRA-Matrix B (d x r)"]
W0 --> Add["Vektoraddition"]
B --> Add
Add --> Y["Ausgabevektor h"]&lt;/div>
&lt;h3 id="32-die-innovation-von-qlora-quantized-lora">3.2 Die Innovation von QLoRA (Quantized LoRA)
&lt;/h3>&lt;p>QLoRA treibt den Ansatz von LoRA weiter voran, indem das Basismodell $W_0$ in 4-Bit-Präzision (NormalFloat 4, NF4) quantisiert und in den Speicher geladen wird. Dies reduziert den VRAM-Verbrauch drastisch.&lt;/p>
&lt;p>In QLoRA sind drei wichtige Technologien integriert:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>4-bit NormalFloat (NF4) Quantisierung:&lt;/strong> Ein theoretisch optimaler Datentyp, der für normalverteilte Gewichte optimiert ist.&lt;/li>
&lt;li>&lt;strong>Double Quantization (Doppelte Quantisierung):&lt;/strong> Spart noch mehr Speicherplatz, indem die Quantisierungskonstante (Skalierungsfaktor) selbst quantisiert wird.&lt;/li>
&lt;li>&lt;strong>Paged Optimizers:&lt;/strong> Ein Mechanismus, der die Unified-Memory-Funktion von NVIDIA nutzt, um Optimizer-Statusse bei VRAM-Mangel vorübergehend in den RAM der CPU auszulagern.&lt;/li>
&lt;/ol>
&lt;p>Dadurch kann ein Tuning, das normalerweise 16 GB bis 24 GB VRAM benötigt, selbst auf Consumer-GPUs (wie RTX 3060 12 GB oder RTX 4070) mühelos durchgeführt werden.&lt;/p>
&lt;hr>
&lt;h2 id="4-hardwareanforderungen-und-einrichtung-in-der-on-premises-umgebung">4. Hardwareanforderungen und Einrichtung in der On-Premises-Umgebung
&lt;/h2>&lt;p>Die Hardwareanforderungen für die Feinabstimmung von TinyLLaMA (1,1B) mit QLoRA können sehr niedrig gehalten werden.&lt;/p>
&lt;h3 id="empfohlene-hardwarespezifikationen">Empfohlene Hardwarespezifikationen
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>GPU:&lt;/strong> NVIDIA RTX 3060 (12GB), RTX 3090/4090 (24GB) oder NVIDIA A10G/A100 usw. Ein Minimum von 8 GB VRAM ist für den Betrieb ausreichend, aber 12 GB oder mehr werden empfohlen, um größere Batch-Größen zu ermöglichen.&lt;/li>
&lt;li>&lt;strong>CPU:&lt;/strong> Moderne CPU mit 8 oder mehr Kernen (Intel Core i7/i9, AMD Ryzen 7/9)&lt;/li>
&lt;li>&lt;strong>RAM:&lt;/strong> 32 GB oder mehr (Wichtig als Auslagerungsziel für den VRAM bei Verwendung von Paged Optimizers)&lt;/li>
&lt;li>&lt;strong>Speicher:&lt;/strong> NVMe SSD (Zur Beschleunigung des Ladens von Datensätzen und des Speicherns von Modellen)&lt;/li>
&lt;/ul>
&lt;h3 id="einrichtung-der-softwareumgebung">Einrichtung der Softwareumgebung
&lt;/h3>&lt;p>Dies ist ein Einrichtungsprozess, der für eine Ubuntu 22.04 LTS-Umgebung vorgesehen ist. Python 3.10 oder höher wird verwendet.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Virtuelle Umgebung erstellen und aktivieren&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">python3 -m venv tinyllama_env
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">source&lt;/span> tinyllama_env/bin/activate
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># PyTorch installieren (für CUDA 12.1)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Transformer-bezogene Bibliotheken installieren&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install transformers datasets peft trl accelerate bitsandbytes
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="5-optimierungstechnologien-für-schnellstes-tuning">5. Optimierungstechnologien für schnellstes Tuning
&lt;/h2>&lt;p>Um das Tuning nicht nur einfach durchzuführen, sondern &amp;ldquo;am schnellsten&amp;rdquo; abzuschließen, müssen die folgenden Optimierungsmethoden kombiniert werden.&lt;/p>
&lt;h3 id="51-flash-attention-2">5.1 Flash Attention 2
&lt;/h3>&lt;p>Der Standard-Attention-Mechanismus hat eine Zeit- und Raumkomplexität von $O(N^2)$ für die Sequenzlänge $N$. Flash Attention 2 optimiert die Speicherzugriffe zwischen dem SRAM der GPU und dem HBM (High Bandwidth Memory), wodurch E/A-Engpässe ohne Reduzierung der Berechnungskomplexität beseitigt werden. Dies beschleunigt das Training um ein Vielfaches und reduziert den Speicherverbrauch drastisch.&lt;/p>
&lt;h3 id="52-gradient-checkpointing-gradienten-checkpointing">5.2 Gradient Checkpointing (Gradienten-Checkpointing)
&lt;/h3>&lt;p>Hierbei werden nicht alle im Vorwärtsdurchlauf (Forward Pass) berechneten Zwischenaktivierungen im VRAM gespeichert, sondern nur ein Teil davon. Diese werden dann bei Bedarf im Rückwärtsdurchlauf (Backward Pass) neu berechnet. Die Berechnungszeit erhöht sich zwar um etwa 20 %, aber der Speicherverbrauch kann drastisch gesenkt werden, was letztendlich die Einstellung größerer Batch-Größen und eine Erhöhung des Gesamtdurchsatzes ermöglicht.&lt;/p>
&lt;h3 id="53-mixed-precision-training-gemischte-genauigkeit-und-bfloat16">5.3 Mixed Precision Training (Gemischte Genauigkeit) und Bfloat16
&lt;/h3>&lt;p>Um die Tensor Cores der GPU optimal zu nutzen, werden die Trainingsberechnungen in &lt;code>bfloat16&lt;/code> (Brain Floating Point) durchgeführt. Im Vergleich zu &lt;code>float16&lt;/code> ist die Bitlänge des Exponenten dieselbe wie bei &lt;code>float32&lt;/code>, sodass das Risiko von Overflows und Underflows extrem gering ist, was zu einem stabileren Training führt.&lt;/p>
&lt;hr>
&lt;h2 id="6-praxis-qlora-fine-tuning-code-für-tinyllama">6. Praxis: QLoRA Fine-Tuning Code für TinyLLaMA
&lt;/h2>&lt;p>Lassen Sie uns nun das PyTorch-Skript für das schnellste Tuning erläutern, das alle oben genannten Optimierungen enthält. Hier verwenden wir den &lt;code>SFTTrainer&lt;/code> aus der Bibliothek &lt;code>trl&lt;/code> (Transformer Reinforcement Learning) von Hugging Face.&lt;/p>
&lt;h3 id="61-vorbereiten-des-datensatzes-und-laden-des-modells">6.1 Vorbereiten des Datensatzes und Laden des Modells
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">torch&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">datasets&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">load_dataset&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">transformers&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">AutoModelForCausalLM&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">AutoTokenizer&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">BitsAndBytesConfig&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">TrainingArguments&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">peft&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">LoraConfig&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">get_peft_model&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">prepare_model_for_kbit_training&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">trl&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">SFTTrainer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 1. Spezifikation von Modell und Tokenizer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">model_id&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;TinyLlama/TinyLlama-1.1B-Chat-v1.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 2. 4-Bit-Quantisierungseinstellungen für QLoRA&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">bnb_config&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">BitsAndBytesConfig&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">load_in_4bit&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">bnb_4bit_use_double_quant&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">bnb_4bit_quant_type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;nf4&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">bnb_4bit_compute_dtype&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">torch&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">bfloat16&lt;/span> &lt;span class="c1"># Berechnungen in bfloat16 durchführen&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 3. Laden des Modells (Flash Attention 2 aktivieren)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Loading model...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">model&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">AutoModelForCausalLM&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_pretrained&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">model_id&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">quantization_config&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">bnb_config&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">device_map&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;auto&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">use_flash_attention_2&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span> &lt;span class="c1"># Schlüssel zur maximalen Geschwindigkeit&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 4. Laden des Tokenizers&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">tokenizer&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">AutoTokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_pretrained&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model_id&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">trust_remote_code&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">tokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">pad_token&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">tokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">eos_token&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">tokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">padding_side&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;right&amp;#34;&lt;/span> &lt;span class="c1"># Auf right setzen, um Bugs während fp16/bf16-Trainings zu vermeiden&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="62-anwendung-des-lora-adapters-und-formatierung-des-datensatzes">6.2 Anwendung des LoRA-Adapters und Formatierung des Datensatzes
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 5. Vorbereitung auf k-Bit-Training und Aktivierung des Gradient Checkpointings&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">model&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">gradient_checkpointing_enable&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">model&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">prepare_model_for_kbit_training&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 6. LoRA-Konfiguration&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">peft_config&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">LoraConfig&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">r&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">16&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Rang&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">lora_alpha&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">32&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Skalierungsfaktor&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">lora_dropout&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">0.05&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">bias&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;none&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">task_type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;CAUSAL_LM&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">target_modules&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;q_proj&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;k_proj&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;v_proj&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;o_proj&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;gate_proj&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;up_proj&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;down_proj&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="c1"># Die Einbeziehung aller linearen Schichten verbessert die Leistung&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">model&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">get_peft_model&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">peft_config&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">model&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">print_trainable_parameters&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Ausgabebeispiel: trainable params: 14,286,848 || all params: 1,114,335,232 || trainable%: 1.282%&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 7. Laden des Datensatzes (Hier verwenden wir als Beispiel einen japanischen Instruction-Datensatz)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># In der Praxis laden Sie z.B. private JSONL-Dateien aus der On-Premises-Umgebung&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">dataset&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">load_dataset&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;kunishou/databricks-dolly-15k-ja&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">split&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;train&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">format_instruction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sample&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> Formatiert den String so, dass er zum ChatML-Format oder Prompt-Template passt
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> &amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">prompt&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&amp;lt;|im_start|&amp;gt;user&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">sample&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;instruction&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">sample&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;input&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">prompt&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">sample&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;input&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">prompt&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&amp;lt;|im_end|&amp;gt;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">&amp;lt;|im_start|&amp;gt;assistant&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">sample&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;output&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;lt;|im_end|&amp;gt;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;text&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">prompt&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">dataset&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">dataset&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">map&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">format_instruction&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="63-ausführung-des-trainings">6.3 Ausführung des Trainings
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 8. Einstellen der Trainingsargumente&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">training_args&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">TrainingArguments&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">output_dir&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;./tinyllama-lora-output&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">per_device_train_batch_size&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">8&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Erhöhen, falls noch VRAM verfügbar ist&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">gradient_accumulation_steps&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Effektive Batch-Größe = 8 * 2 = 16&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">optim&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;paged_adamw_32bit&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># VRAM-Einsparung durch Paged Optimizer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">save_steps&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">100&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">logging_steps&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">learning_rate&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">2e-4&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">fp16&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">False&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">bf16&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Gemischte Genauigkeit (bfloat16)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">max_grad_norm&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">0.3&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">max_steps&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">500&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># 500 Schritte zu Testzwecken. In der Produktion durch Epochenanzahl angeben&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">warmup_ratio&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">0.03&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">group_by_length&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">lr_scheduler_type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;cosine&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 9. Starten des Trainings mit SFTTrainer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">trainer&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">SFTTrainer&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">model&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">train_dataset&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">dataset&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">peft_config&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">peft_config&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dataset_text_field&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;text&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">max_seq_length&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">1024&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Anpassen an die erwartete Eingabelänge&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">tokenizer&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">tokenizer&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">args&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">training_args&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Starting training...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">trainer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">train&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 10. Speichern des LoRA-Adapters&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">trainer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">save_pretrained&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;./tinyllama-lora-final&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">tokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">save_pretrained&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;./tinyllama-lora-final&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Training complete and model saved.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="7-leistungsbewertung-und-fehlerbehebung">7. Leistungsbewertung und Fehlerbehebung
&lt;/h2>&lt;p>Dies sind häufig auftretende Probleme und deren Lösungen beim Training in On-Premises-Umgebungen.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>OOM (Out Of Memory) tritt auf:&lt;/strong>
&lt;ul>
&lt;li>Senken Sie &lt;code>per_device_train_batch_size&lt;/code> auf &lt;code>1&lt;/code>.&lt;/li>
&lt;li>Erhöhen Sie &lt;code>gradient_accumulation_steps&lt;/code>, um die effektive Batch-Größe beizubehalten.&lt;/li>
&lt;li>Verkürzen Sie &lt;code>max_seq_length&lt;/code> von &lt;code>2048&lt;/code> auf &lt;code>1024&lt;/code> oder &lt;code>512&lt;/code>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>Loss sinkt nicht oder divergiert:&lt;/strong>
&lt;ul>
&lt;li>Möglicherweise ist die Lernrate (&lt;code>learning_rate&lt;/code>) zu hoch. Versuchen Sie, sie von &lt;code>2e-4&lt;/code> auf etwa &lt;code>5e-5&lt;/code> zu senken.&lt;/li>
&lt;li>Wenn Float16 anstelle von Bfloat16 verwendet wird, könnte ein Gradienten-Underflow auftreten. Stellen Sie sicher, dass &lt;code>bf16=True&lt;/code> gesetzt ist.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>Bei der Inferenz werden mysteriöse Zeichenketten generiert:&lt;/strong>
&lt;ul>
&lt;li>Stellen Sie sicher, dass &lt;code>padding_side=&amp;quot;right&amp;quot;&lt;/code> korrekt eingestellt ist. Darüber hinaus muss überprüft werden, ob das Datensatzformat (Spezial-Token wie &lt;code>&amp;lt;|im_start|&amp;gt;&lt;/code>) mit dem des Basismodells beim Vortraining übereinstimmt.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="8-modellbereitstellung-deployment-nach-dem-tuning">8. Modellbereitstellung (Deployment) nach dem Tuning
&lt;/h2>&lt;p>Wenn das Tuning abgeschlossen ist, wird nicht das &amp;ldquo;gesamte Basismodell&amp;rdquo; gespeichert, sondern nur der wenige MB bis Dutzende MB große &amp;ldquo;&lt;strong>LoRA-Adapter (Differenzgewichte)&lt;/strong>&amp;rdquo;. Um eine schnelle Inferenz durchzuführen, müssen diese LoRA-Gewichte mit dem ursprünglichen Basismodell zusammengeführt (gemergt) und als einzelnes Modell exportiert werden.&lt;/p>
&lt;h3 id="skript-zum-mergen-des-modells">Skript zum Mergen des Modells
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">torch&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">peft&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">AutoPeftModelForCausalLM&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">transformers&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">AutoTokenizer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">output_dir&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;./tinyllama-lora-final&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Laden von Modell und Adapter in FP16/BF16&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">model&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">AutoPeftModelForCausalLM&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_pretrained&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">output_dir&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">device_map&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;auto&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">torch_dtype&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">torch&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">bfloat16&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">tokenizer&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">AutoTokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_pretrained&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">output_dir&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Gewichte zusammenführen und speichern&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">merged_model&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">model&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">merge_and_unload&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">merged_model&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">save_pretrained&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;./tinyllama-merged&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">safe_serialization&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">tokenizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">save_pretrained&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;./tinyllama-merged&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Model merged and saved successfully!&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="aufbau-eines-extrem-schnellen-inferenzservers-mit-vllm">Aufbau eines extrem schnellen Inferenzservers mit vLLM
&lt;/h3>&lt;p>Um den Inferenzdurchsatz (Tokens per second) in On-Premises-Umgebungen zu maximieren, wird dringend empfohlen, &lt;strong>vLLM&lt;/strong> oder &lt;strong>TGI (Text Generation Inference)&lt;/strong> anstelle der Standard-&lt;code>pipeline&lt;/code> von Hugging Face zu verwenden. vLLM verwendet die PagedAttention-Technologie, um Speicherfragmentierung der GPU zu verhindern und die Verarbeitungskapazität für gleichzeitige Anfragen drastisch zu verbessern.&lt;/p>
&lt;p>Das folgende Mermaid-Diagramm zeigt die Pipeline vom Training bis zur Bereitstellung auf dem Inferenzserver.&lt;/p>
&lt;div class="mermaid">graph TD
A["Rohe private Daten"] --> B["Vorverarbeitung &amp; Formatierung (JSONL)"]
B --> C["QLoRA Fine-Tuning (SFTTrainer)"]
C --> D["LoRA-Adaptergewichte (.safetensors)"]
D --> E["Zusammenführung mit Basis-TinyLLaMA 1,1B"]
E --> F["Zusammengeführtes Modell"]
F --> G["Bereitstellung über vLLM-Server"]
G --> H["API-Endpunkt / UI (z. B. Chatbot)"]&lt;/div>
&lt;p>Das Starten des API-Servers mit vLLM ist mit folgendem Einzelbefehl erledigt:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">python -m vllm.entrypoints.openai.api_server &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --model ./tinyllama-merged &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --host 0.0.0.0 &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --port &lt;span class="m">8000&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --max-model-len &lt;span class="m">2048&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --dtype bfloat16
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Damit ist ein mit der OpenAI-API kompatibler Endpunkt in der On-Premises-Umgebung eingerichtet, wodurch die lokale KI sicher und mit hoher Geschwindigkeit genutzt werden kann.&lt;/p>
&lt;hr>
&lt;h2 id="9-fazit">9. Fazit
&lt;/h2>&lt;p>Dieser Artikel erläuterte Methoden zur schnellsten und speichereffizientesten Feinabstimmung von &amp;ldquo;TinyLLaMA&amp;rdquo;, einem Modell, das trotz seiner kompakten Größe von 1,1B Parametern eine hohe Leistung bietet, in einer On-Premises-Umgebung.&lt;/p>
&lt;ul>
&lt;li>Durch &lt;strong>LoRA / QLoRA&lt;/strong> ist ein vollwertiges LLM-Tuning auch auf Consumer-GPUs möglich.&lt;/li>
&lt;li>Die Nutzung von &lt;strong>Flash Attention 2&lt;/strong> und &lt;strong>Gradient Checkpointing&lt;/strong> optimiert die Trainingszeit und den VRAM-Verbrauch auf das Äußerste.&lt;/li>
&lt;li>Durch die Bereitstellung mit &lt;strong>vLLM&lt;/strong> wird auch in Produktionsumgebungen ein hoher Durchsatz erzielt.&lt;/li>
&lt;/ul>
&lt;p>Der lokale Betrieb von LLMs vor Ort schützt nicht nur die Datenvertraulichkeit, sondern ist auch die stärkste Waffe zum Aufbau spezialisierter KI für bestimmte Domänen (wie Recht, Medizin, interne Vorschriften usw.) zu geringen Kosten. Nutzen Sie diesen Leitfaden gerne als Referenz, um Ihr eigenes unternehmensspezifisches TinyLLaMA zu entwickeln.&lt;/p></description></item><item><title>Entwicklungsschritte für kleine KI-Modelle (wie TinyLLaMA) mit C++</title><link>http://kenji.blog/de/p/cpp-small-ai-model-tinyllama-dev-guide/</link><pubDate>Fri, 11 Sep 2026 14:00:00 +0900</pubDate><guid>http://kenji.blog/de/p/cpp-small-ai-model-tinyllama-dev-guide/</guid><description>&lt;img src="http://kenji.blog/p/cpp-small-ai-model-tinyllama-dev-guide/img/eyecatch.jpg" alt="Featured image of post Entwicklungsschritte für kleine KI-Modelle (wie TinyLLaMA) mit C++" />&lt;h1 id="entwicklungsschritte-für-kleine-ki-modelle-wie-tinyllama-mit-c">Entwicklungsschritte für kleine KI-Modelle (wie TinyLLaMA) mit C++
&lt;/h1>&lt;p>In den letzten Jahren ist das Interesse an der Ausführung von Large Language Models (LLMs) in lokalen Umgebungen rasant gestiegen. Insbesondere kleine Modelle wie TinyLLaMA (1,1B Parameter) können selbst auf Edge-Geräten mit begrenzten Ressourcen oder herkömmlichen Laptops (einschließlich Windows-Umgebungen) mit praktischer Geschwindigkeit für Inferenzen genutzt werden. Während die Entwicklung hauptsächlich mit Python und PyTorch erfolgt, ist die Kombination aus C++ und „ggml“, einer C-basierten Tensor-Bibliothek, zum De-facto-Standard geworden, wenn es darum geht, die ultimative Leistung und Speichereffizienz zu erreichen.&lt;/p>
&lt;p>In diesem Artikel werden wir die detaillierten Entwicklungsschritte erläutern, um eine Inferenz-Engine von Grund auf aufzubauen (oder die interne Struktur der bestehenden llama.cpp tiefgehend zu verstehen), mit der TinyLLaMA in C++ geladen und Text generiert wird.&lt;/p>
&lt;hr>
&lt;h2 id="1-warum-c-und-ggml">1. Warum C++ und ggml?
&lt;/h2>&lt;p>In der Trainingsphase von KI ist Python mit seiner Flexibilität und seinem umfangreichen Ökosystem überwältigend im Vorteil. In der Bereitstellungs- oder „Inferenz“-Phase wird C++ jedoch aus den folgenden Gründen zu einer leistungsstarken Option.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Reduzierung von Overhead&lt;/strong>: Das Global Interpreter Lock (GIL) von Python und der Runtime-Overhead können vollständig eliminiert werden.&lt;/li>
&lt;li>&lt;strong>Speichereffizienz und Arena-Allokation&lt;/strong>: Da die Zuweisung und Freigabe von Speicher manuell gesteuert werden können, lassen sich unvorhersehbare Spitzen (Spikes) durch die Garbage Collection verhindern.&lt;/li>
&lt;li>&lt;strong>Direkter Zugriff auf die Hardware&lt;/strong>: SIMD-Intrinsics wie AVX-512, AVX2 und ARM NEON können direkt aufgerufen werden, um die Rechenleistung der CPU zu maximieren.&lt;/li>
&lt;li>&lt;strong>Keine Abhängigkeiten&lt;/strong>: ggml ist eine C/C++-Bibliothek ohne Abhängigkeiten (Zero dependencies) und kann problemlos auf Windows-Umgebungen mit MSVC kompiliert werden, solange ein Compiler vorhanden ist.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="2-gesamtbild-der-architektur">2. Gesamtbild der Architektur
&lt;/h2>&lt;p>Der Fluss der gesamten Inferenz-Pipeline ist im folgenden Mermaid-Diagramm dargestellt. Dies ist der Prozess vom Eingabetext des Benutzers bis zur endgültigen Generierung des nächsten Tokens.&lt;/p>
&lt;div class="mermaid">graph TD
A["Benutzereingabetext"] --> B["BPE Tokenizer"]
B --> C["Token-IDs Array"]
C --> D["Embedding Layer Lookup"]
D --> E["Transformer Blocks"]
E --> F["RMSNorm"]
F --> G["LM Head Layer"]
G --> H["Logits Array"]
H --> I["Sampler-Modul"]
I --> J["Nächste Token-ID"]
J --> K["Detokenizer"]
K --> L["Ausgabetext-Chunk"]
J -.-> |"Zum Kontext hinzufügen"| C&lt;/div>
&lt;p>Da es sich um ein autoregressives Modell handelt, wird das ausgegebene Token wieder dem Kontext hinzugefügt und als Eingabe für die Vorhersage des nächsten Tokens zyklisch verwendet (gestrichelte Linie im Diagramm).&lt;/p>
&lt;hr>
&lt;h2 id="3-modellformat-und-memory-mapping-mmap">3. Modellformat und Memory Mapping (mmap)
&lt;/h2>&lt;p>Das größte Hindernis beim Umgang mit den Gewichten riesiger neuronaler Netze sind Festplatten-I/O und Speicherverbrauch. In der C++-Implementierung wird dies durch &lt;strong>Memory Mapping (mmap)&lt;/strong> gelöst.&lt;/p>
&lt;h3 id="31-funktionsweise-von-memory-mapping-und-implementierung-in-windows">3.1 Funktionsweise von Memory Mapping und Implementierung in Windows
&lt;/h3>&lt;p>Mit mmap kann der Inhalt einer Datei direkt in den virtuellen Adressraum des Prozesses abgebildet (gemappt) werden.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Zero-copy&lt;/strong>: Die Daten werden von der Festplatte direkt in den Page-Cache des Kernels geladen, ohne dass eine zusätzliche Kopie in den Userspace erfolgt.&lt;/li>
&lt;li>&lt;strong>On-Demand-Laden (Page Fault)&lt;/strong>: In dem Moment, in dem die CPU tatsächlich auf diese Speicheradresse zugreift, tritt ein Page Fault (Seitenfehler) auf, und nur der benötigte Chunk (normalerweise 4 KB) wird in den physischen Speicher geladen.&lt;/li>
&lt;/ul>
&lt;p>In Windows-Umgebungen werden anstelle des POSIX &lt;code>mmap&lt;/code> die Win32-APIs &lt;code>CreateFileMapping&lt;/code> und &lt;code>MapViewOfFile&lt;/code> verwendet.&lt;/p>
&lt;div class="mermaid">sequenceDiagram
participant OS["Windows OS"]
participant RAM["Physischer Speicher"]
participant App["C++ Anwendung"]
App->>OS: "CreateFileMapping / MapViewOfFile"
OS-->>App: "Zeiger auf virtuelle Speicheradresse"
App->>App: "Tensor-Daten am Zeiger lesen"
OS->>RAM: "Page Fault / Seite von der Festplatte laden"
RAM-->>App: "Daten bereit für SIMD-Berechnung"&lt;/div>
&lt;h3 id="32-binäre-struktur-des-gguf-formats">3.2 Binäre Struktur des GGUF-Formats
&lt;/h3>&lt;p>Das aus Formaten wie &lt;code>.safetensors&lt;/code> von Hugging Face konvertierte &lt;strong>GGUF (GPT-Generated Unified Format)&lt;/strong> ist das ultimative Format für Inferenzen. Es verfügt über das folgende strikte binäre Layout.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Magic Bytes&lt;/strong>: &lt;code>0x46554747&lt;/code> (GGUF).&lt;/li>
&lt;li>&lt;strong>Version&lt;/strong>: Die Versionsnummer des Formats.&lt;/li>
&lt;li>&lt;strong>Tensor Count &amp;amp; Metadata Count&lt;/strong>: Anzahl der Tensoren und der Metadaten-Schlüssel-Wert-Paare.&lt;/li>
&lt;li>&lt;strong>Metadata (Key-Value Pairs)&lt;/strong>: Schlüssel mit Präfix für die Zeichenfolgenlänge und typisierte Werte.&lt;/li>
&lt;li>&lt;strong>Tensor Info&lt;/strong>: Name, Dimensionen, Datentyp (FP16, Q4_K usw.) jedes Tensors und die Offset-Position in der Datei.&lt;/li>
&lt;li>&lt;strong>Padding&lt;/strong>: Polsterung (Padding), die eingefügt wird, damit die Tensordaten an bestimmten Grenzen (normalerweise 32 oder 64 Byte) ausgerichtet (aligned) werden. Dies ist entscheidend für den schnellen Speicherzugriff mit SIMD-Befehlen (insbesondere AVX).&lt;/li>
&lt;li>&lt;strong>Tensor Data&lt;/strong>: Das eigentliche Array der ausgerichteten Gewichtsdaten.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="4-mathematische-grundlagen-von-tinyllama-und-c-algorithmen">4. Mathematische Grundlagen von TinyLLaMA und C++-Algorithmen
&lt;/h2>&lt;p>TinyLLaMA beinhaltet einige fortgeschrittene architektonische Tricks zur Effizienzsteigerung. Die mathematischen Ausdrücke zur korrekten Implementierung in C++ werden hier erläutert.&lt;/p>
&lt;h3 id="41-rmsnorm-root-mean-square-normalization">4.1 RMSNorm (Root Mean Square Normalization)
&lt;/h3>&lt;p>Die Rechenkosten werden reduziert, indem die Mittelwert-Zentrierung aus LayerNorm weggelassen und nur die Varianz-Skalierung durchgeführt wird.&lt;/p>
$$ \text{RMSNorm}(x) = \frac{x}{\sqrt{\frac{1}{d}\sum_{i=1}^{d} x_i^2 + \epsilon}} \odot \gamma $$
&lt;p>$d$ ist die Anzahl der Dimensionen, $\gamma$ ist der gelernte Skalierungstensor.
Bei der Implementierung in C++ wird dies optimiert, indem zunächst die Summe der Quadrate des Arrays schnell mit AVX2s &lt;code>_mm256_fmadd_ps&lt;/code> etc. berechnet wird und dann mit der inversen Quadratwurzel (z. B. &lt;code>_mm256_rsqrt_ps&lt;/code> Befehl) multipliziert wird.&lt;/p>
&lt;h3 id="42-rope-rotary-position-embedding">4.2 RoPE (Rotary Position Embedding)
&lt;/h3>&lt;p>Eine Technik, um die Positionsinformationen von Tokens als Rotation im Tensorraum anzuwenden. Es kann als Rotation auf einer komplexen Ebene betrachtet werden, wobei für benachbarte Dimensionspaare $(x_1, x_2)$ des Vektors $x$ die folgende Rotation angewendet wird.&lt;/p>
$$ \text{RoPE}(x, m) = \begin{pmatrix} x_{1} \cos(m\theta) - x_{2} \sin(m\theta) \\ x_{1} \sin(m\theta) + x_{2} \cos(m\theta) \end{pmatrix} $$
&lt;p>Hier ist $m$ der absolute Positionsindex des Tokens und $\theta$ die vorberechnete Grundfrequenz. In ggml wird es parallel ausgeführt, indem einfach der &lt;code>ggml_rope&lt;/code>-Operator während der Konstruktion des Inferenzgraphen hinzugefügt wird.&lt;/p>
&lt;h3 id="43-grouped-query-attention-gqa">4.3 Grouped-Query Attention (GQA)
&lt;/h3>&lt;p>Bei der normalen Multi-Head Attention (MHA) gibt es die gleiche Anzahl von Heads für Query, Key und Value. TinyLLaMA verwendet jedoch &lt;strong>Grouped-Query Attention (GQA)&lt;/strong>, um die Speicherbandbreite und den KV-Cache-Verbrauch drastisch zu reduzieren.&lt;/p>
$$ \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{Q K^T}{\sqrt{d_k}}\right) V $$
&lt;p>Bei GQA teilen sich mehrere Query-Heads einen Key/Value-Head. In der C++-Implementierung ist es erforderlich, den KV-Tensor so zu broadcasten (zu replizieren), dass er der Anzahl der Queries entspricht, bevor die Matrixmultiplikation &lt;code>ggml_mul_mat&lt;/code> ausgeführt wird.&lt;/p>
&lt;h3 id="44-swiglu-aktivierungsfunktion">4.4 SwiGLU-Aktivierungsfunktion
&lt;/h3>&lt;p>Im Feed-Forward Network (FFN)-Layer wird anstelle von GELU SwiGLU verwendet.&lt;/p>
$$ \text{SwiGLU}(x) = \text{Swish}(x W_{\text{gate}}) \otimes (x W_{\text{up}}) $$
$$ \text{Swish}(z) = z \cdot \sigma(z) = z \cdot \frac{1}{1 + e^{-z}} $$
&lt;p>Im Berechnungsgraphen wird dies durch eine Kombination aus dem &lt;code>ggml_silu&lt;/code>-Operator und &lt;code>ggml_mul&lt;/code> dargestellt.&lt;/p>
&lt;hr>
&lt;h2 id="5-konstruktion-des-berechnungsgraphen-mit-ggml-und-speicherverwaltung">5. Konstruktion des Berechnungsgraphen mit ggml und Speicherverwaltung
&lt;/h2>&lt;p>ggml verfolgt einen „Define-and-Run“-Ansatz, bei dem ein statischer Berechnungsgraph für die Inferenz konstruiert und anschließend evaluiert wird.&lt;/p>
&lt;h3 id="51-ggml_context-und-arena-allocator">5.1 ggml_context und Arena-Allocator
&lt;/h3>&lt;p>Die einzigartigste Eigenschaft von ggml ist die „Arena-Allokation“, bei der in der Inferenzschleife keinerlei dynamische Speicherzuweisungen (&lt;code>malloc&lt;/code> oder &lt;code>new&lt;/code>) stattfinden.
Bei der Initialisierung wird ein riesiger zusammenhängender Speicherbereich (die Arena) reserviert, und bei jedem Aufruf von z. B. &lt;code>ggml_new_tensor&lt;/code> wird der Zeiger dieses Bereichs inkrementiert. Sobald ein Inferenzschritt abgeschlossen ist, wird der Allokationszeiger einfach auf seine Ausgangsposition zurückgesetzt, wodurch die Speicherzuweisung für den nächsten Inferenzschritt sofort abgeschlossen ist.&lt;/p>
&lt;h3 id="52-konkretes-beispiel-für-die-konstruktion-eines-graphen">5.2 Konkretes Beispiel für die Konstruktion eines Graphen
&lt;/h3>&lt;p>Für jeden Inferenzschritt wird der folgende Berechnungsgraph im Speicher aufgebaut.&lt;/p>
&lt;div class="mermaid">graph TD
A["Eingabe-Token-ID"] --> B["Embed Lookup"]
B --> C["ggml_rms_norm"]
C --> D["Q / K / V Projektionen"]
D --> E["ggml_rope Positional"]
E --> F["KV Cache Speichern"]
E --> G["KV Cache Laden"]
G --> H["Self Attention"]
H --> I["Skalierung &amp; Softmax"]
I --> J["Attention Ausgabe"]
J --> K["Out Projektion"]
K --> L["Residual Hinzufügen"]&lt;/div>
&lt;hr>
&lt;h2 id="6-quantisierung-quantization-und-windows--simd-optimierung">6. Quantisierung (Quantization) und Windows / SIMD-Optimierung
&lt;/h2>&lt;p>Wenn TinyLLaMA (1,1B) in FP16 verwendet wird, werden etwa 2,2 GB Speicher benötigt, aber durch 4-Bit-Quantisierung (wie Q4_K) kann dies drastisch auf etwa 600 MB komprimiert werden.&lt;/p>
&lt;h3 id="61-block-quantisierungsarchitektur">6.1 Block-Quantisierungsarchitektur
&lt;/h3>&lt;p>ggml quantisiert nicht den gesamten Tensor einheitlich, sondern in „Blöcken“.
Im &lt;code>Q4_0&lt;/code>-Format werden 32 FP16-Werte in einem Block zusammengefasst.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Skalierungsfaktor (Scale Factor)&lt;/strong>: Ein FP16-Wert (2 Byte)&lt;/li>
&lt;li>&lt;strong>Quantisierte Daten&lt;/strong>: 32 4-Bit-Werte (16 Byte)
Dadurch wird der Einfluss von lokalen Ausreißern (Outliers) minimiert.&lt;/li>
&lt;/ul>
&lt;h3 id="62-beschleunigung-des-skalarprodukts-durch-avx2">6.2 Beschleunigung des Skalarprodukts durch AVX2
&lt;/h3>&lt;p>Beim Kompilieren für die neuesten x86-CPUs in einer Windows-Umgebung werden Compiler-Flags wie &lt;code>/arch:AVX2&lt;/code> verwendet und die SIMD-Verarbeitung läuft im folgenden Fluss ab:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Laden&lt;/strong>: Die quantisierten 4-Bit-Daten werden aus dem Speicher in ein 256-Bit-AVX-Register geladen.&lt;/li>
&lt;li>&lt;strong>Entpacken (Unpack)&lt;/strong>: Die 4-Bit-Werte werden durch Bitmasken- und Shift-Operationen in Int8 oder Int16 entpackt.&lt;/li>
&lt;li>&lt;strong>Dequantisierung&lt;/strong>: Multiplikation mit dem Skalierungsfaktor zur Umwandlung in Gleitkommazahlen.&lt;/li>
&lt;li>&lt;strong>FMA-Berechnung&lt;/strong>: Parallele Ausführung der Multiply-Add-Operation mit den Aktivierungswerten über &lt;code>_mm256_fmadd_ps&lt;/code> (Fused Multiply-Add).&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="7-details-zur-implementierung-des-kv-caches">7. Details zur Implementierung des KV-Caches
&lt;/h2>&lt;p>Bei der autoregressiven Generierung ist ein „KV-Cache“, der die Berechnung von Key und Value vergangener Tokens überspringt, eine zwingend erforderliche Funktion.&lt;/p>
&lt;p>Bei der Implementierung in C++ sind die folgenden Punkte wichtig:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Vorabreservierung des Tensors&lt;/strong>: Ein riesiger Tensor für die maximale Kontextlänge (z. B. 2048 Tokens) wird für den KV-Cache initialisiert (FP16 wird empfohlen).&lt;/li>
&lt;li>&lt;strong>Offset-Kopie&lt;/strong>: Wenn die Berechnung für die Token-Position $N$ durchgeführt wird, werden die in diesem Schritt erhaltenen K- und V-Vektoren in der $N$-ten Zeile des KV-Cache-Tensors mithilfe von &lt;code>ggml_cpy&lt;/code> o. Ä. gespeichert.&lt;/li>
&lt;li>&lt;strong>Erstellung eines Views bei der Attention&lt;/strong>: Bei der Berechnung der Attention wird ein „View“ (Ansicht) erstellt, der nur auf den Bereich der Tokens 0 bis $N$ verweist, und dieser View wird an die Matrixmultiplikation übergeben.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="8-bpe-tokenizer-und-dekodierung">8. BPE Tokenizer und Dekodierung
&lt;/h2>&lt;p>Der Eingabe-String wird als Bytefolge in UTF-8 behandelt und mit einem vordefinierten Vokabular abgeglichen. Um die Vokabularsuche in C++ zu beschleunigen, werden Algorithmen implementiert, die &lt;strong>Trie-Bäume (Präfixbäume)&lt;/strong> oder Prioritätswarteschlangen verwenden.&lt;/p>
&lt;p>Die vom LM Head ausgegebenen Logits werden mithilfe des Temperature-Parameters skaliert, um Wahrscheinlichkeiten zu erhalten. Die Kandidaten werden durch Top-K-Extraktion oder Top-P-Methoden (Nucleus Sampling) eingegrenzt, und das endgültige nächste Token wird mithilfe von Zufallszahlen bestimmt.&lt;/p>
&lt;hr>
&lt;h2 id="9-aufbau-eines-c-projekts-windows--powershell-umgebung">9. Aufbau eines C++-Projekts (Windows / PowerShell-Umgebung)
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cmake" data-lang="cmake">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cmake_minimum_required&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">VERSION&lt;/span> &lt;span class="s">3.14&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">project&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">TinyLLaMACpp&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CMAKE_CXX_STANDARD&lt;/span> &lt;span class="s">17&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># Optimierungs- und AVX2-Flags für Windows (MSVC)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MSVC&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">add_compile_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">/O2&lt;/span> &lt;span class="s">/arch:AVX2&lt;/span> &lt;span class="s">/fp:fast&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">add_link_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">/STACK:8388608&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">else&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">add_compile_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">-O3&lt;/span> &lt;span class="s">-march=native&lt;/span> &lt;span class="s">-ffast-math&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">endif&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">add_library&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">ggml&lt;/span> &lt;span class="s">OBJECT&lt;/span> &lt;span class="s">ggml/ggml.c&lt;/span> &lt;span class="s">ggml/ggml-alloc.c&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">target_compile_definitions&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">ggml&lt;/span> &lt;span class="s">PRIVATE&lt;/span> &lt;span class="s">GGML_USE_AVX2&lt;/span> &lt;span class="s">GGML_USE_F16C&lt;/span> &lt;span class="s">GGML_USE_FMA&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">add_executable&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">main&lt;/span> &lt;span class="s">main.cpp&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">target_link_libraries&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">main&lt;/span> &lt;span class="s">ggml&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Beispiel für einen Build-Befehl in PowerShell:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">mkdir&lt;/span> &lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd &lt;/span>&lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cmake&lt;/span> &lt;span class="p">..&lt;/span> &lt;span class="n">-G&lt;/span> &lt;span class="s2">&amp;#34;Visual Studio 17 2022&amp;#34;&lt;/span> &lt;span class="n">-A&lt;/span> &lt;span class="n">x64&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cmake&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-build&lt;/span> &lt;span class="p">.&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-config&lt;/span> &lt;span class="n">Release&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="10-zusammenfassung">10. Zusammenfassung
&lt;/h2>&lt;p>Die Implementierung einer Inferenz-Engine für kleine KI-Modelle wie TinyLLaMA von Grund auf mit C++ und ggml ist eine hervorragende Gelegenheit, die Blackbox des Deep Learning zu entschlüsseln und die Schönheit der Low-Level-Hardwaresteuerung kennenzulernen. Durch den Einsatz von Zero-Copy-Laden mithilfe von Memory Mapping, SIMD-Optimierung und dem Aufbau von KV-Caches können Sie das Wesentliche der Systemprogrammierung in vollen Zügen genießen und gleichzeitig die Zukunft der Edge-KI mitgestalten.&lt;/p></description></item><item><title>【2026 Aktuell】Der ultimative Leitfaden zur Ausführung von lokalen LLMs unter Windows</title><link>http://kenji.blog/de/p/local-llm-windows-2026/</link><pubDate>Fri, 11 Sep 2026 10:00:00 +0900</pubDate><guid>http://kenji.blog/de/p/local-llm-windows-2026/</guid><description>&lt;img src="http://kenji.blog/p/local-llm-windows-2026/img/eyecatch.jpg" alt="Featured image of post 【2026 Aktuell】Der ultimative Leitfaden zur Ausführung von lokalen LLMs unter Windows" />&lt;h1 id="1-einführung-warum-gerade-jetzt-lokale-llms-unter-windows">1. Einführung: Warum gerade jetzt lokale LLMs unter Windows?
&lt;/h1>&lt;p>Im Jahr 2026 hat die Entwicklung generativer KI und großer Sprachmodelle (LLMs) einen gewaltigen Paradigmenwechsel vollzogen – von riesigen API-Diensten in der Cloud hin zu &amp;ldquo;lokalen LLMs&amp;rdquo;, die auf privaten PCs oder in On-Premise-Umgebungen laufen. Cloud-KIs wie GPT-5 von OpenAI und Claude 3.5 von Anthropic sind extrem leistungsstark, aber Unternehmen und Privatpersonen können nicht all ihre Daten in die Cloud senden. Aus Gründen des Datenschutzes, der Sicherheit, der Latenzzeit sowie der langfristigen und nachhaltigen Kosten ist die Nachfrage nach lokalen LLMs so explosionsartig gestiegen wie nie zuvor.&lt;/p>
&lt;p>Besonders im Windows-Umfeld ist die Entwicklung des Ökosystems für lokale LLMs bemerkenswert. Noch vor einigen Jahren galt &amp;ldquo;KI-Entwicklung und -Ausführung gleich Linux&amp;rdquo; als gängige Regel, doch im Jahr 2026 hat sich Windows zu einer äußerst leistungsstarken und zugänglichen KI-Plattform gewandelt.&lt;/p>
&lt;p>In diesem Artikel bieten wir einen vollständigen Leitfaden zur Einrichtung, zum Betrieb und zur Optimierung lokaler LLMs in einer Windows-Umgebung, basierend auf den neuesten Technologietrends von 2026. Von der einfachen Einrichtung für Anfänger mit Ollama über die extreme Optimierung für Fortgeschrittene mithilfe von llama.cpp bis hin zu tiefergehenden mathematischen Ansätzen zur VRAM-Berechnung, dem Verständnis der Architektur und lokalem Fine-Tuning – wir erklären alles ausführlich und in gewaltigem Umfang.&lt;/p>
&lt;h2 id="11-technologietrends-rund-um-lokale-llms-im-jahr-2026">1.1 Technologietrends rund um lokale LLMs im Jahr 2026
&lt;/h2>&lt;p>Die wichtigsten Trends, die das aktuelle Ökosystem für lokale LLMs prägen, sind:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Vollständige Verbreitung des GGUF-Formats&lt;/strong>: GGUF (GPT-Generated Unified Format), das Metadaten und Tensoren in einer einzigen Datei vereint, hat sich vollständig als De-facto-Standard etabliert. Dadurch genügt es, eine einzige Datei von Hugging Face herunterzuladen, um sie in beliebigen Umgebungen auszuführen.&lt;/li>
&lt;li>&lt;strong>Demokratisierung der MoE-Architektur (Mixture of Experts)&lt;/strong>: Es wurden zahlreiche kleine, aber leistungsstarke MoE-Modelle veröffentlicht. Indem während der Inferenz nur ein Teil der Experten aktiviert wird, erreichen sie die Leistung riesiger Modelle, während die Rechenlast für Consumer-PCs gering gehalten wird.&lt;/li>
&lt;li>&lt;strong>Fortgeschrittene Abstraktion und Optimierung von Inferenz-Engines&lt;/strong>: Tools wie Ollama, LM Studio und AnythingLLM wurden so verfeinert, dass sich der Benutzer nicht mehr um komplexe Abhängigkeiten wie die Installation von CUDA-Treibern kümmern muss. Zudem hat die native Windows-Unterstützung von FlashAttention 3 die Inferenzgeschwindigkeit drastisch erhöht.&lt;/li>
&lt;li>&lt;strong>Nutzung von NPUs und der Aufstieg von Windows Copilot+ PCs&lt;/strong>: Die Technologie zur Ausführung kleiner LLMs (SLM: Small Language Models) mit geringem Stromverbrauch unter Nutzung der verbauten NPU (Neural Processing Unit) hat auch bei Laptops ohne GPU die Praxisreife erreicht.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h1 id="2-hardwareanforderungen-und-os-vorbereitung">2. Hardwareanforderungen und OS-Vorbereitung
&lt;/h1>&lt;p>Um ein lokales LLM mit praktikabler Geschwindigkeit (15 bis 30 Token pro Sekunde oder mehr) auszuführen, ist die Wahl der Hardware von entscheidender Bedeutung.&lt;/p>
&lt;h2 id="21-empfohlene-hardwarekonfiguration">2.1 Empfohlene Hardwarekonfiguration
&lt;/h2>&lt;p>Mit der Weiterentwicklung von AI-PCs haben sich auch die Spezifikationsanforderungen geändert.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>OS&lt;/strong>: Windows 11 Pro (24H2 oder neuer). Zwingend erforderlich für die volle Funktionalität von WSL2, erweitertes Speichermanagement sowie die Nutzung der neuesten APIs von DirectML.&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: Intel Core Ultra 200 Serie oder neuer, bzw. AMD Ryzen 9000 Serie oder neuer. Bei gleichzeitiger Nutzung der CPU-Inferenz ist eine hohe Speicherbandbreite unerlässlich.&lt;/li>
&lt;li>&lt;strong>RAM&lt;/strong>: Mindestens 32 GB, empfohlen 64 GB oder mehr. Die Bandbreite des Hauptspeichers (MB/s) wird zum entscheidenden Flaschenhals bei CPU-Inferenz oder Offloading. Schneller DDR5-6000 Speicher oder höher ist ideal.&lt;/li>
&lt;li>&lt;strong>GPU&lt;/strong>: NVIDIA RTX 4000/5000 Serie. Bei lokalen LLMs ist nicht die Rechenleistung, sondern die &amp;ldquo;VRAM-Kapazität&amp;rdquo; das Wichtigste.
&lt;ul>
&lt;li>&lt;strong>Einsteiger&lt;/strong>: RTX 4060 Ti (16GB-Version) - Bestes Preis-Leistungs-Verhältnis. Ideal für Modelle der 8B- bis 14B-Klasse.&lt;/li>
&lt;li>&lt;strong>Mittelklasse&lt;/strong>: RTX 4070 Ti SUPER (16GB) / RTX 4080 SUPER (16GB)&lt;/li>
&lt;li>&lt;strong>High-End&lt;/strong>: RTX 4090 (24GB) / RTX 5090 (32GB) - Erforderlich für die Ausführung quantisierter Modelle der 30B- bis 70B-Klasse.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>Speicher&lt;/strong>: PCIe Gen4 oder Gen5 NVMe SSD. Reduziert die Ladezeiten für zig Gigabyte große Modelle drastisch.&lt;/li>
&lt;/ul>
&lt;h2 id="22-einrichtung-von-wsl2-windows-subsystem-for-linux-2">2.2 Einrichtung von WSL2 (Windows Subsystem for Linux 2)
&lt;/h2>&lt;p>Viele GUI-Tools laufen nativ unter Windows, aber für die Python-Entwicklung, das Kompilieren neuester Tools und das spätere LoRA-Fine-Tuning ist WSL2 äußerst praktisch. In den neuesten Windows 11-Umgebungen muss lediglich der NVIDIA-Treiber auf dem Host installiert werden, um die GPU (CUDA) transparent aus WSL2 heraus nutzen zu können.&lt;/p>
&lt;p>Öffnen Sie PowerShell mit Administratorrechten und führen Sie Folgendes aus:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># Installation von WSL2 und dem neuesten Ubuntu&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">wsl&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-install&lt;/span> &lt;span class="n">-d&lt;/span> &lt;span class="n">Ubuntu&lt;/span>&lt;span class="p">-&lt;/span>&lt;span class="mf">24.04&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># Kernel-Update&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">wsl&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-update&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Führen Sie nach der Installation &lt;code>nvidia-smi&lt;/code> im WSL2-Terminal aus. Wenn die GPU korrekt erkannt wird, war die Einrichtung erfolgreich.&lt;/p>
&lt;hr>
&lt;h1 id="3-architektur-lokaler-llms-und-inferenzmechanismus">3. Architektur lokaler LLMs und Inferenzmechanismus
&lt;/h1>&lt;p>Das Verständnis der internen Struktur, wie ein Modell in einer lokalen Umgebung Text generiert, ist für die Fehlerbehebung und Optimierung äußerst nützlich.&lt;/p>
&lt;p>Das folgende Mermaid-Diagramm zeigt eine typische Inferenz-Pipeline eines lokalen LLMs.&lt;/p>
&lt;div class="mermaid">graph TD
User["Benutzereingabe (Prompt)"] --> Tokenizer["Tokenizer (Tokenizer)"]
Tokenizer --> Embedding["Embedding-Schicht (Embedding)"]
subgraph "Transformer Block (x Layers)"
Embedding --> Attn["Selbst-Aufmerksamkeit (Self-Attention)"]
Attn --> KVCache["KV-Cache (Key/Value-Erhalt)"]
Attn --> FFN["Feed-Forward-Netzwerk (FFN)"]
end
FFN --> Logits["Logit-Berechnung (Logits)"]
Logits --> Sampler["Sampler (Temperature, Top-K, Top-P)"]
Sampler --> OutputToken["Ausgabe-Token"]
OutputToken --> |"Autoregressive Generierung"| Tokenizer
OutputToken --> Decoder["Detokenizer (Detokenizer)"]
Decoder --> FinalOutput["Finaler Ausgabetext"]&lt;/div>
&lt;h2 id="31-zwei-phasen-prefill-und-decode">3.1 Zwei Phasen: Prefill und Decode
&lt;/h2>&lt;p>Die Textgenerierung bei LLMs unterteilt sich in zwei Phasen mit unterschiedlichen Berechnungseigenschaften.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Prefill-Phase (Prompt-Verarbeitung)&lt;/strong>: In dieser Phase wird der gesamte eingegebene Prompt auf einmal verarbeitet und verstanden. Da parallele Berechnungen möglich sind, steht die Rechenleistung der GPU (FLOPS) in direktem Zusammenhang mit der Geschwindigkeit. Bei langen Prompts kann diese Phase mehrere Sekunden dauern.&lt;/li>
&lt;li>&lt;strong>Decode-Phase (Token-Generierung)&lt;/strong>: In dieser Phase wird iterativ ein Token vorhergesagt und als nächste Eingabe zurückgeführt (autoregressiv). Da hier parallele Berechnungen eingeschränkt sind, wird die VRAM-Bandbreite (Memory Bandwidth) der GPU zum entscheidenden Flaschenhals.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h1 id="4-berechnung-des-vram-verbrauchs-und-mathematisches-verständnis-der-modellgröße">4. Berechnung des VRAM-Verbrauchs und mathematisches Verständnis der Modellgröße
&lt;/h1>&lt;p>Um richtig einschätzen zu können, &amp;ldquo;welches Modell auf meinem PC läuft&amp;rdquo;, muss man die Berechnungsformel für den VRAM verstehen. Ein Fallback auf den Systemspeicher (RAM) aufgrund von VRAM-Mangel macht die Inferenzgeschwindigkeit 10- bis 100-mal langsamer.&lt;/p>
&lt;h2 id="41-basis-vram-basierend-auf-der-parametergröße">4.1 Basis-VRAM basierend auf der Parametergröße
&lt;/h2>&lt;p>Dies ist die Speichermenge, die benötigt wird, um die Gewichte (Weights) des Modells in den VRAM zu laden.
Sie wird anhand der Modellgröße $P$ (Anzahl der Parameter, Einheit: 1 Milliarde = 1B) und der Anzahl der Bytes pro Parameter $B$ berechnet.&lt;/p>
$$
V_{base} = P \times B \quad \text{(GB)}
$$
&lt;p>Wenn Sie beispielsweise ein 8B (8 Milliarden) Parameter-Modell in FP16 (Halbgenauigkeits-Gleitkommazahl, 16 Bit = 2 Byte) laden:&lt;/p>
$$
V_{base} = 8 \times 2 = 16 \text{ GB}
$$
&lt;p>Das bedeutet, selbst wenn Ihre GPU 16 GB VRAM hat, ist allein durch das Laden des Modells das Limit fast erreicht.&lt;/p>
&lt;h2 id="42-die-magie-der-quantisierung-quantization">4.2 Die Magie der Quantisierung (Quantization)
&lt;/h2>&lt;p>Hier kommt die &amp;ldquo;Quantisierung&amp;rdquo; ins Spiel. Durch Verringern der Parametergenauigkeit wird die Modellgröße drastisch reduziert. Bei der gängigsten 4-Bit-Quantisierung (z. B. Q4_K_M) beträgt ein Parameter im Durchschnitt etwa 0,55 Byte.&lt;/p>
$$
V_{base\_4bit} = 8 \times 0.55 = 4.4 \text{ GB}
$$
&lt;p>Dadurch können Sie mit 16 GB VRAM problemlos ein 8B-Modell mit ausreichend Spielraum ausführen.&lt;/p>
&lt;h2 id="43-berechnung-des-kv-caches-gqa-unterstützte-version">4.3 Berechnung des KV-Caches (GQA-unterstützte Version)
&lt;/h2>&lt;p>Während der Inferenz verbraucht der &amp;ldquo;KV-Cache&amp;rdquo;, der den bisherigen Kontext speichert, VRAM. In neuesten Modellen wie Llama 3 wird GQA (Grouped Query Attention) eingesetzt, um Speicher zu sparen.&lt;/p>
&lt;p>Der Verbrauch des KV-Caches $V_{kv}$ (in Gigabyte) lässt sich durch folgende Formel darstellen:&lt;/p>
$$
V_{kv} = 2 \times b \times s \times l \times \left( \frac{h_{kv}}{h_q} \right) \times h_q \times d \times B_{kv} \div 10^9
$$
&lt;p>Vereinfacht ausgedrückt, kann es mithilfe der Anzahl der Key- und Value-Köpfe $h_{kv}$ einfach berechnet werden:&lt;/p>
$$
V_{kv} = 2 \times b \times s \times l \times h_{kv} \times d \times B_{kv} \div 10^9
$$
&lt;p>Hierbei ist:&lt;/p>
&lt;ul>
&lt;li>$b$: Batch-Größe (bei lokaler Einzelnutzung meist 1)&lt;/li>
&lt;li>$s$: Sequenzlänge (Kontextlänge, z. B. 8192)&lt;/li>
&lt;li>$l$: Anzahl der Schichten (Layer, z. B. 32)&lt;/li>
&lt;li>$h_{kv}$: Anzahl der KV-Köpfe (KV-Heads, z. B. 8)&lt;/li>
&lt;li>$d$: Dimensionalität pro Kopf (z. B. 128)&lt;/li>
&lt;li>$B_{kv}$: Bytegröße des KV-Caches (2 für FP16)&lt;/li>
&lt;/ul>
&lt;p>Berechnungsbeispiel (Llama 3 8B, Kontext 8192, FP16 Cache):
$V_{kv} = 2 \times 1 \times 8192 \times 32 \times 8 \times 128 \times 2 \div 10^9 \approx 1.07 \text{ GB}$&lt;/p>
&lt;p>Beachten Sie, dass der erforderliche VRAM linear ansteigt, je länger die Kontextlänge $s$ gewählt wird.&lt;/p>
&lt;hr>
&lt;h1 id="5-praxis-1-schnellstes-und-kürzestes-setup-mit-ollama">5. Praxis 1: Schnellstes und kürzestes Setup mit Ollama
&lt;/h1>&lt;p>Da wir nun die Theorie verstehen, lassen Sie uns ein LLM tatsächlich in einer Windows-Umgebung ausführen.
Im Jahr 2026 ist das benutzerfreundlichste Tool &amp;ldquo;Ollama&amp;rdquo;. Es bietet ein Docker-ähnliches, intuitives CLI.&lt;/p>
&lt;h2 id="51-installation-und-ausführung">5.1 Installation und Ausführung
&lt;/h2>&lt;ol>
&lt;li>Laden Sie den Windows-Installer von der &lt;a class="link" href="https://ollama.com/" target="_blank" rel="noopener"
>offiziellen Ollama-Website&lt;/a> herunter und führen Sie ihn aus.&lt;/li>
&lt;li>Öffnen Sie PowerShell und geben Sie den folgenden Befehl ein. Hier verwenden wir das japanischsprachige &lt;code>llama3:8b&lt;/code>.&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">ollama&lt;/span> &lt;span class="n">run&lt;/span> &lt;span class="n">llama3&lt;/span>&lt;span class="err">:&lt;/span>&lt;span class="n">8b&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Beim ersten Ausführen wird das Modell heruntergeladen. Sobald dies abgeschlossen ist, können Sie direkt im Terminal chatten.&lt;/p>
&lt;h2 id="52-erstellen-einer-benutzerdefinierten-ki-mit-modelfile">5.2 Erstellen einer benutzerdefinierten KI mit Modelfile
&lt;/h2>&lt;p>Sie können ganz einfach eine KI mit einer bestimmten Persona erstellen. Erstellen Sie ein &lt;code>Modelfile&lt;/code> an einem beliebigen Ort.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">FROM llama3:8b
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">SYSTEM &amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Sie sind ein hervorragender Senior-Software-Ingenieur.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Beantworten Sie Benutzerfragen stets mit Codebeispielen, logisch und präzise.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PARAMETER temperature 0.3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PARAMETER num_ctx 8192
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Erstellen und starten Sie Ihr eigenes Modell mit den folgenden Befehlen:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">ollama&lt;/span> &lt;span class="n">create&lt;/span> &lt;span class="n">SeniorDev&lt;/span> &lt;span class="o">-f&lt;/span> &lt;span class="p">./&lt;/span>&lt;span class="n">Modelfile&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">ollama&lt;/span> &lt;span class="n">run&lt;/span> &lt;span class="n">SeniorDev&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="53-nutzung-über-externe-apps-ki-editoren">5.3 Nutzung über externe Apps (KI-Editoren)
&lt;/h2>&lt;p>Ollama stellt einen OpenAI-kompatiblen API-Endpunkt unter &lt;code>http://localhost:11434&lt;/code> zur Verfügung.
Indem Sie diese URL in den Backend-Einstellungen von VS-Code-Erweiterungen wie Cursor oder Continue.dev angeben und als Modellnamen z.B. &lt;code>SeniorDev&lt;/code> festlegen, erhalten Sie kostenlos einen leistungsstarken lokalen Coding-Assistenten.&lt;/p>
&lt;hr>
&lt;h1 id="6-praxis-2-extreme-leistungsoptimierung-mit-llamacpp">6. Praxis 2: Extreme Leistungsoptimierung mit llama.cpp
&lt;/h1>&lt;p>Wenn Sie feinkörnige Speicherverwaltung wünschen oder die neuesten Formate (wie EXL2 oder IQ-Quantisierung) schnell ausprobieren möchten, steuern Sie die Kern-Engine &lt;code>llama.cpp&lt;/code> direkt.&lt;/p>
&lt;h2 id="61-schritte-zum-kompilieren-von-llamacpp">6.1 Schritte zum Kompilieren von llama.cpp
&lt;/h2>&lt;p>In einer Windows-Umgebung ist es am besten, mithilfe von CUDA Toolkit und CMake aus dem Quellcode zu kompilieren.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">git&lt;/span> &lt;span class="n">clone&lt;/span> &lt;span class="n">https&lt;/span>&lt;span class="err">:&lt;/span>&lt;span class="p">//&lt;/span>&lt;span class="n">github&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">com&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="n">ggerganov&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="n">llama&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cpp
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd &lt;/span>&lt;span class="n">llama&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cpp
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">&lt;/span>&lt;span class="n">mkdir&lt;/span> &lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd &lt;/span>&lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># Für CUDA konfigurieren und kompilieren&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cmake&lt;/span> &lt;span class="p">..&lt;/span> &lt;span class="n">-DLLAMA_CUBLAS&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="n">ON&lt;/span> &lt;span class="n">-DBUILD_SHARED_LIBS&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="n">OFF&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cmake&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-build&lt;/span> &lt;span class="p">.&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-config&lt;/span> &lt;span class="n">Release&lt;/span> &lt;span class="n">-j&lt;/span> &lt;span class="mf">16&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="62-fortgeschrittener-start-im-server-modus">6.2 Fortgeschrittener Start im Server-Modus
&lt;/h2>&lt;p>Verwenden Sie die kompilierte &lt;code>llama-server.exe&lt;/code>, um das Modell zu hosten.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="p">.\&lt;/span>&lt;span class="n">bin&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">Release&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="nb">llama-server&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">exe&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-model&lt;/span> &lt;span class="s2">&amp;#34;C:\models\Llama-3-8B-Instruct.Q4_K_M.gguf&amp;#34;&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-ctx-size&lt;/span> &lt;span class="mf">8192&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-n-gpu-layers&lt;/span> &lt;span class="mf">99&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-threads&lt;/span> &lt;span class="mf">8&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-flash-attn&lt;/span> &lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">-&lt;/span>&lt;span class="n">-port&lt;/span> &lt;span class="mf">8080&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;ul>
&lt;li>&lt;code>--n-gpu-layers 99&lt;/code>: Verlagert so viele Layer wie möglich auf den GPU VRAM.&lt;/li>
&lt;li>&lt;code>--flash-attn&lt;/code>: Aktiviert FlashAttention 3, um die Inferenzgeschwindigkeit zu erhöhen und den VRAM-Verbrauch des KV-Caches zu senken.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h1 id="7-gui-frontends-lm-studio-und-aufbau-lokaler-rags">7. GUI-Frontends: LM Studio und Aufbau lokaler RAGs
&lt;/h1>&lt;p>Wenn Sie die Kommandozeile meiden möchten oder RAG (Retrieval-Augmented Generation) intuitiv umsetzen wollen, nutzen Sie eine GUI.&lt;/p>
&lt;h2 id="71-lm-studio">7.1 LM Studio
&lt;/h2>&lt;p>LM Studio ist eine fantastische Anwendung, die Modellsuche, Download, Überprüfung der Systemanforderungen und eine Chat-UI in einem vereint. Durch einfaches Klicken auf den Button &amp;ldquo;Local Server&amp;rdquo; in der App wird eine OpenAI-kompatible API gestartet.&lt;/p>
&lt;h2 id="72-rag-architektur-mit-anythingllm">7.2 RAG-Architektur mit AnythingLLM
&lt;/h2>&lt;p>Hier ist das Architekturdiagramm einer RAG-Umgebung zum Einlesen interner Dokumente oder privater Notizen.&lt;/p>
&lt;div class="mermaid">graph LR
Document["Dokument (PDF, MD)"] --> Chunking["Chunk-Aufteilung"]
Chunking --> EmbedModel["Embedding-Modell"]
EmbedModel --> VectorDB["Vektordatenbank"]
UserQuery["Benutzeranfrage"] --> EmbedQuery["Anfrage-Embedding"]
EmbedQuery --> VectorDB
VectorDB --> |"Ähnlichkeitssuche"| RetrievedDocs["Extrahierte relevante Dokumente"]
UserQuery --> PromptBuilder["Prompt-Generierung"]
RetrievedDocs --> PromptBuilder
PromptBuilder --> LocalLLM["Lokales LLM"]
LocalLLM --> Answer["Finale Antwort"]&lt;/div>
&lt;p>Mit der Desktop-Version von AnythingLLM (für Windows) können Sie diese Architektur in wenigen Minuten aufbauen, indem Sie in den Einstellungen Ollama (für LLM und Embedding) auswählen und eine lokale Vektor-DB (LanceDB) festlegen. Dies ist die Geburtsstunde einer privaten KI, die keinerlei Daten nach außen sendet.&lt;/p>
&lt;hr>
&lt;h1 id="8-fine-tuning-lora-auf-windows-wsl2">8. Fine-Tuning (LoRA) auf Windows WSL2
&lt;/h1>&lt;p>Wenn Sie Modelle nicht nur lokal ausführen, sondern mit Ihren eigenen Daten intelligenter machen wollen, ist ein Fine-Tuning mit LoRA (Low-Rank Adaptation) möglich. Im Jahr 2026 können Sie mit der Bibliothek &amp;ldquo;Unsloth&amp;rdquo; in einer Windows WSL2-Umgebung das Training eines 8B-Modells mit 16 GB VRAM in wenigen Stunden abschließen.&lt;/p>
&lt;p>Richten Sie die Umgebung ein, indem Sie Folgendes in WSL2 Ubuntu ausführen:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">conda create --name unsloth_env &lt;span class="nv">python&lt;/span>&lt;span class="o">=&lt;/span>3.11
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">conda activate unsloth_env
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install &lt;span class="s2">&amp;#34;unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install --no-deps trl peft accelerate bitsandbytes
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Unsloth optimiert CUDA-Kernel bis zum Äußersten, verdoppelt die Trainingsgeschwindigkeit im Vergleich zu Standard-Hugging-Face-Bibliotheken und halbiert den VRAM-Verbrauch. Starten Sie einfach ein Jupyter Notebook, laden Sie Ihren Datensatz (im JSONL-Format) ein, und schon ist ein Training über mehrere Epochen selbst auf einer RTX 4060 Ti mit 12 GB bis 16 GB VRAM möglich.&lt;/p>
&lt;hr>
&lt;h1 id="9-leistungs-fehlerbehebung-troubleshooting">9. Leistungs-Fehlerbehebung (Troubleshooting)
&lt;/h1>&lt;p>Häufig auftretende Probleme und deren Lösungen.&lt;/p>
&lt;h3 id="1-inferenzgeschwindigkeit-ist-extrem-langsam-1-2-tokenss">1. Inferenzgeschwindigkeit ist extrem langsam (1-2 tokens/s)
&lt;/h3>&lt;p>&lt;strong>Ursache&lt;/strong>: Das Modell passt nicht in den VRAM und wird auf den Systemspeicher (RAM) ausgelagert.
&lt;strong>Lösung&lt;/strong>: Überprüfen Sie den &amp;ldquo;Dedizierten GPU-Speicher&amp;rdquo; im Task-Manager. Wenn das Limit erreicht ist, verringern Sie die Kontextgröße (&lt;code>-c&lt;/code>) oder verwenden Sie ein quantisiertes Modell mit niedrigerer Bitrate (z. B. Q4_K_M).&lt;/p>
&lt;h3 id="2-cuda-out-of-memory-fehler">2. &amp;ldquo;CUDA out of memory&amp;rdquo; Fehler
&lt;/h3>&lt;p>&lt;strong>Ursache&lt;/strong>: Der VRAM ist vollständig erschöpft. Tritt besonders dann auf, wenn der Dialog lang wird und der KV-Cache anwächst.
&lt;strong>Lösung&lt;/strong>: Begrenzen Sie bewusst die Werte für &lt;code>num_ctx&lt;/code> bei Ollama oder &lt;code>-c&lt;/code> bei llama.cpp.&lt;/p>
&lt;h3 id="3-japanische-oder-eine-andere-generierung-ist-seltsam">3. Japanische (oder eine andere) Generierung ist seltsam
&lt;/h3>&lt;p>&lt;strong>Ursache&lt;/strong>: Falsches Prompt-Template oder inkompatibles Modell.
&lt;strong>Lösung&lt;/strong>: Verwenden Sie Modelle, die &lt;code>Instruct&lt;/code> im Namen tragen, und stellen Sie sicher, dass das vom Modellautor angegebene korrekte Template (wie ChatML oder Llama3-Format) im Tool ausgewählt ist.&lt;/p>
&lt;hr>
&lt;h1 id="10-zusammenfassung-und-zukünftige-aussichten">10. Zusammenfassung und zukünftige Aussichten
&lt;/h1>&lt;p>Im Jahr 2026 ist der Aufbau lokaler LLMs unter Windows kein Privileg mehr für eine kleine Gruppe von Ingenieuren. Durch den De-facto-Standard des GGUF-Formats, das Erscheinen ausgereifter Ökosysteme wie Ollama und LM Studio und Hardware-Optimierungen wie FlashAttention kann heute jeder ganz einfach eine KI-Umgebung auf Unternehmensniveau einrichten.&lt;/p>
&lt;p>Bitte nutzen Sie die in diesem Artikel erläuterten Punkte:&lt;/p>
&lt;ol>
&lt;li>Wählen Sie durch &lt;strong>mathematische VRAM-Berechnungen&lt;/strong> logisch die optimale Modellgröße und Quantisierungsstufe für die Spezifikationen Ihres PCs aus.&lt;/li>
&lt;li>Bauen Sie mit &lt;strong>Ollama&lt;/strong> in kürzester Zeit eine Umgebung auf und steigern Sie die Produktivität drastisch durch die Integration mit einem KI-Editor.&lt;/li>
&lt;li>Holen Sie durch erweiterte Parametersteuerung mit &lt;strong>llama.cpp&lt;/strong> die maximale Leistung aus Ihrer Hardware heraus.&lt;/li>
&lt;li>Errichten Sie mit &lt;strong>AnythingLLM&lt;/strong> ein sicheres lokales RAG-System, das auch vertrauliche Daten verarbeiten kann.&lt;/li>
&lt;li>Nutzen Sie &lt;strong>Unsloth (WSL2)&lt;/strong>, um Ihre eigene benutzerdefinierte KI mit Fachwissen zu trainieren.&lt;/li>
&lt;/ol>
&lt;p>Die &amp;ldquo;Demokratisierung&amp;rdquo; der KI ist nicht länger nur ein Schlagwort, sondern ein reales System, das auf Ihrem Windows-Desktop läuft. Befreien Sie sich von Cloud-API-Kosten sowie Risiken von Informationslecks und treten Sie noch heute in die freie und mächtige Welt der privaten KI ein.&lt;/p></description></item></channel></rss>