<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>LLM on kenji.blog</title><link>http://kenji.blog/de/tags/llm/</link><description>Recent content in LLM on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>de</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 11:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/de/tags/llm/index.xml" rel="self" type="application/rss+xml"/><item><title>Einführung in die Nutzung und C++-Anpassung von llama.cpp</title><link>http://kenji.blog/de/p/llama-cpp-cxx-customization/</link><pubDate>Fri, 11 Sep 2026 11:00:00 +0900</pubDate><guid>http://kenji.blog/de/p/llama-cpp-cxx-customization/</guid><description>&lt;img src="http://kenji.blog/p/llama-cpp-cxx-customization/img/eyecatch.jpg" alt="Featured image of post Einführung in die Nutzung und C++-Anpassung von llama.cpp" />&lt;p>In den letzten Jahren war die Entwicklung von Large Language Models (LLMs) enorm und ihre Anwendungsbereiche erweitern sich täglich. Um jedoch Modelle mit Milliarden oder zig Milliarden Parametern in einer lokalen Umgebung auszuführen, benötigt man normalerweise eine High-End-GPU mit enorm viel VRAM. &lt;strong>llama.cpp&lt;/strong> hat diese „Hardware-Barriere“ durchbrochen und ermöglicht praktische LLM-Inferenz auf gewöhnlichen PCs, Macs und sogar auf Geräten wie dem Raspberry Pi.&lt;/p>
&lt;p>In diesem Artikel erklären wir nicht nur die Nutzung als reines Kommandozeilentool, sondern gehen für Entwickler äußerst detailliert auf die zugrunde liegende &lt;code>ggml&lt;/code>-Architektur, den mathematischen Hintergrund von Transformern und Quantisierung sowie die Nutzung der C++-API ein, um LLMs in eigene Anwendungen zu integrieren und anzupassen.&lt;/p>
&lt;hr>
&lt;h2 id="1-übersicht-über-llamacpp-und-ggml">1. Übersicht über llama.cpp und ggml
&lt;/h2>&lt;p>&lt;code>llama.cpp&lt;/code> ist eine von Georgi Gerganov in C/C++ geschriebene, leichtgewichtige LLM-Inferenz-Engine. Ursprünglich wurde sie entwickelt, um Metas LLaMA-Modelle auf Apple Silicon (M1/M2 Macs) mit hoher Geschwindigkeit auszuführen, unterstützt aber mittlerweile verschiedene Architekturen und Modelle.&lt;/p>
&lt;p>Das größte Merkmal ist, dass es sich um eine &lt;strong>reine C/C++-Implementierung ohne externe Abhängigkeiten&lt;/strong> handelt. Da kein riesiges Ökosystem wie Python oder PyTorch benötigt wird und es als einzelne ausführbare Datei kompiliert werden kann, ist die Bereitstellung extrem einfach.&lt;/p>
&lt;p>Das Herzstück von &lt;code>llama.cpp&lt;/code> ist die Tensor-Berechnungsbibliothek &lt;strong>ggml&lt;/strong>. ggml wurde von Grund auf neu entwickelt, um Matrixoperationen für maschinelles Lernen auf der CPU (und teilweise GPU) bis zum Äußersten zu optimieren.&lt;/p>
&lt;h3 id="11-warum-ist-llamacpp-so-schnell">1.1 Warum ist llama.cpp so schnell?
&lt;/h3>&lt;ol>
&lt;li>&lt;strong>Nutzung von Memory Mapping (mmap)&lt;/strong>: Beim Laden der Modellgewichte in den Speicher wird durch die Nutzung der &lt;code>mmap&lt;/code>-Funktion des Betriebssystems das vollständige Laden in den RAM vermieden, was zu einem schnellen Start und Speicherplatzeinsparungen führt.&lt;/li>
&lt;li>&lt;strong>Umfassende Optimierung von SIMD-Befehlen&lt;/strong>: CPU-spezifische Befehlssätze wie AVX2, AVX-512, ARM NEON und Apple AMX werden genutzt, um Matrixmultiplikationen extrem zu beschleunigen.&lt;/li>
&lt;li>&lt;strong>Quantisierung (Quantization)&lt;/strong>: Die Gewichte in 16-Bit-Gleitkommazahlen (FP16) werden in 4-Bit-, 5-Bit- oder 8-Bit-Ganzzahlen komprimiert, um Engpässe in der Speicherbandbreite zu beseitigen (Details siehe unten).&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="2-mathematischer-hintergrund-transformer-und-quantisierung">2. Mathematischer Hintergrund: Transformer und Quantisierung
&lt;/h2>&lt;p>Um llama.cpp tiefgreifend zu verstehen, muss man die mathematischen Formeln kennen, die es berechnet, und wissen, wie es diese Berechnungen annähert.&lt;/p>
&lt;h3 id="21-transformer-inferenzprozess">2.1 Transformer-Inferenzprozess
&lt;/h3>&lt;p>Modelle wie LLaMA verwenden eine autoregressive (Auto-regressive) Transformer-Decoder-Architektur. Der Kern der Textgenerierung ist der &lt;strong>Self-Attention&lt;/strong>-Mechanismus.&lt;/p>
&lt;p>Für eine Eingabematrix von verborgenen Zuständen $X \in \mathbb{R}^{N \times d}$ werden Query $Q$, Key $K$ und Value $V$ durch Multiplikation mit Gewichtsmatrizen berechnet:&lt;/p>
$$
Q = X W_Q, \quad K = X W_K, \quad V = X W_V
$$
&lt;p>Hierbei ist die Ausgabe der Attention wie folgt definiert:&lt;/p>
$$
\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V
$$
&lt;p>In der Inferenzschleife von llama.cpp liegt der Engpass in der Multiplikation dieser riesigen Matrizen $W_Q, W_K, W_V$ und der Gewichtsmatrizen des Feed-Forward-Networks (FFN) mit dem Vektor $X$ (da in der Generierungsphase Token für Token verarbeitet wird, ist $N=1$), also &lt;strong>GEMV (General Matrix-Vector Multiplication)&lt;/strong>.&lt;/p>
&lt;h3 id="22-mathematische-grundlagen-der-quantisierung">2.2 Mathematische Grundlagen der Quantisierung
&lt;/h3>&lt;p>In der Inferenz, bei der die Speicherzugriffsbandbreite der Engpass ist, ist die Quantisierung, bei der Gewichtsparameter mit einer kleinen Anzahl von Bits dargestellt werden, unerlässlich. Wir erklären das Grundprinzip der in llama.cpp weit verbreiteten blockweisen Quantisierung (z. B. &lt;code>Q4_K&lt;/code> oder &lt;code>Q4_0&lt;/code>).&lt;/p>
&lt;p>Betrachten wir zum Beispiel einen Block $w = [w_1, w_2, \dots, w_B]$ der Länge $B$ (normalerweise 32 oder 64), der Teil der FP16-Gewichtsmatrix $W$ ist. Dieser Block wird durch eine 4-Bit-Ganzzahl $q_i \in [-8, 7]$ und einen einzelnen Skalierungsfaktor $\Delta$ (FP16 oder FP32) angenähert.&lt;/p>
$$
w_i \approx \Delta \times q_i
$$
&lt;p>$\Delta$ wird basierend auf dem maximalen Absolutwert innerhalb des Blocks bestimmt.&lt;/p>
$$
\Delta = \frac{\max_i |w_i|}{7}
$$
&lt;p>Wenn das Skalarprodukt $y = w \cdot x$ unter Verwendung der quantisierten Gewichte berechnet wird und der Eingabevektor $x$ ebenfalls quantisiert wird, sodass $x_i \approx \Delta_x \times q_{x, i}$, gilt:&lt;/p>
$$
y = \sum_{i=1}^{B} w_i x_i \approx \Delta \Delta_x \sum_{i=1}^{B} q_i q_{x, i}
$$
&lt;p>Dieser Teil $\sum q_i q_{x, i}$ ist eine &lt;strong>reine Ganzzahloperation&lt;/strong> und kann mithilfe von SIMD-Befehlen extrem schnell parallel berechnet werden. Das ist der mathematische Trick, der llama.cpp auf CPUs atemberaubende Geschwindigkeiten erreichen lässt.&lt;/p>
&lt;hr>
&lt;h2 id="3-architektur-und-inferenzfluss">3. Architektur und Inferenzfluss
&lt;/h2>&lt;p>Um die interne Funktionsweise von llama.cpp zu verstehen, zeigt das folgende Mermaid-Diagramm die Gesamtsystemarchitektur und den Datenfluss.&lt;/p>
&lt;div class="mermaid">graph TD
A["Benutzereingabe (String)"] --> B["llama.cpp Tokenizer"]
B --> C["Token-IDs (int32-Array)"]
C --> D["Kontextpuffer (KV Cache)"]
D --> E["ggml-Berechnungsgraph"]
E --> F["Transformer-Schichten"]
subgraph "ggml Engine"
F --> G["Self-Attention (RoPE)"]
G --> H["Feed Forward Network"]
H --> F
end
F --> I["Logits (Vokabulargröße)"]
I --> J["Sampler (Temperature, Top-K, Top-P)"]
J --> K["Ausgewählte Token-ID"]
K --> L["llama.cpp Detokenizer"]
L --> M["Ausgabe-String"]
K -. "Autoregressive Schleife" .-> D&lt;/div>
&lt;p>Die Textgenerierung ist eine autoregressive Schleife, bei der jedes ausgegebene Token als nächste Eingabe in den KV-Cache aufgenommen wird und den Berechnungsgraphen erneut durchläuft.&lt;/p>
&lt;hr>
&lt;h2 id="4-einrichtung-der-umgebung-und-build-methode">4. Einrichtung der Umgebung und Build-Methode
&lt;/h2>&lt;p>Bevor wir llama.cpp in ein C++-Projekt integrieren, lassen Sie uns zunächst den Quellcode kompilieren (builden).&lt;/p>
&lt;h3 id="41-klonen-des-repositorys">4.1 Klonen des Repositorys
&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;/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">git clone https://github.com/ggerganov/llama.cpp.git
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> llama.cpp
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="42-build-mit-cmake">4.2 Build mit CMake
&lt;/h3>&lt;p>Wenn Sie es als C++-Projekt in andere Anwendungen integrieren möchten, ist die Verwendung von CMake der Standardweg. Durch die Aktivierung von plattformspezifischen Beschleunigern (Backends) können Berechnungen beschleunigt werden.&lt;/p>
&lt;p>&lt;strong>Nur CPU (Basis-Build):&lt;/strong>&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;/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">mkdir build &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="nb">cd&lt;/span> build
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cmake ..
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cmake --build . --config Release -j &lt;span class="m">8&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Bei Verwendung einer NVIDIA-GPU (CUDA):&lt;/strong>&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;/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">mkdir build &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="nb">cd&lt;/span> build
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cmake .. -DGGML_CUDA&lt;span class="o">=&lt;/span>ON
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cmake --build . --config Release -j &lt;span class="m">8&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Bei Verwendung von Apple Silicon (Metal):&lt;/strong>&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;/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">mkdir build &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="nb">cd&lt;/span> build
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cmake .. -DGGML_METAL&lt;span class="o">=&lt;/span>ON
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cmake --build . --config Release -j &lt;span class="m">8&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Bei einem erfolgreichen Build werden ausführbare Dateien wie &lt;code>llama-cli&lt;/code> und die &lt;code>llama&lt;/code>-Bibliothek (sowie die &lt;code>ggml&lt;/code>-Bibliothek) zur Verlinkung mit der unten beschriebenen C++-API im Verzeichnis &lt;code>build/bin/&lt;/code> generiert.&lt;/p>
&lt;hr>
&lt;h2 id="5-einführung-in-die-c-anpassung-nutzung-der-llamacpp-api">5. Einführung in die C++-Anpassung: Nutzung der llama.cpp API
&lt;/h2>&lt;p>Von hier an behandeln wir das Hauptthema: die Steuerung von llama.cpp aus C++-Code.
Um ein LLM in Ihre eigenen Anwendungen (z. B. Spiel-Engines, Desktop-Apps, eingebettete Systeme usw.) zu integrieren, anstatt nur das Kommandozeilentool zu verwenden, müssen Sie die C++-API direkt aufrufen.&lt;/p>
&lt;p>llama.cpp bietet hauptsächlich eine C-Schnittstelle über eine Header-Datei namens &lt;code>llama.h&lt;/code>. Auch beim Aufruf aus C++ wird diese Schnittstelle verwendet.&lt;/p>
&lt;h3 id="51-nötigste-includes-und-einstellungen">5.1 Nötigste Includes und Einstellungen
&lt;/h3>&lt;p>Wenn Sie llama.cpp in Ihrem eigenen Projekt verwenden, inkludieren Sie Folgendes:&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;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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;#34;llama.h&amp;#34;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;vector&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;string&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;stdexcept&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Makro zur Fehlerbehandlung
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="cp">#define LLAMA_ASSERT(x) \
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp"> do { \
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp"> if (!(x)) { \
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp"> std::cerr &amp;lt;&amp;lt; &amp;#34;Assertion failed: &amp;#34; &amp;lt;&amp;lt; #x &amp;lt;&amp;lt; std::endl; \
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp"> std::terminate(); \
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp"> } \
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp"> } while (0)
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="52-modell-laden-und-kontext-initialisieren">5.2 Modell laden und Kontext initialisieren
&lt;/h3>&lt;p>Zuerst laden wir die Modelldatei im &lt;code>.gguf&lt;/code>-Format und reservieren den Kontext (Speicherplatz und KV-Cache) für die Inferenz.&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;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-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">argc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">char&lt;/span> &lt;span class="o">**&lt;/span> &lt;span class="n">argv&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">argc&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Usage: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">argv&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34; &amp;lt;model.gguf&amp;gt;&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">1&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 class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">string&lt;/span> &lt;span class="n">model_path&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">argv&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&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">// 1. Initialisierung des Backends (Umgebungs-Setup wie CPU/GPU)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_backend_init&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">// 2. Standardeinstellungen für Modellparameter abrufen
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_model_params&lt;/span> &lt;span class="n">model_params&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_model_default_params&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_params&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">n_gpu_layers&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">35&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Anzahl der auf die GPU ausgelagerten Schichten
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 3. Modell laden
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_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">llama_load_model_from_file&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model_path&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">c_str&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">model_params&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">model&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="k">nullptr&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Failed to load model&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">1&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">// 4. Kontextparameter einstellen
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_context_params&lt;/span> &lt;span class="n">ctx_params&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_context_default_params&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ctx_params&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">n_ctx&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">2048&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Maximale Kontextgröße (Anzahl der Tokens)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">ctx_params&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">n_threads&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">// Anzahl der für die Inferenz verwendeten CPU-Threads
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 5. Kontext erstellen
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_context&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">ctx&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_new_context_with_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">ctx_params&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">ctx&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="k">nullptr&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Failed to create context&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_free_model&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 class="k">return&lt;/span> &lt;span class="mi">1&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="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Model and context loaded successfully!&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// ... folgende Verarbeitung
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="53-tokenisierung-des-prompts-tokenization">5.3 Tokenisierung des Prompts (Tokenization)
&lt;/h3>&lt;p>LLMs verstehen Text nicht direkt, sondern verarbeiten ihn als eine Reihe von ganzzahligen IDs (Tokens). Die Eingabezeichenfolge muss in Tokens umgewandelt werden.&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;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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">string&lt;/span> &lt;span class="n">prompt&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s">&amp;#34;Q: Was ist die Hauptstadt von Japan?&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">A:&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">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">llama_token&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">tokens_list&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">tokens_list&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">resize&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">prompt&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">length&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">4&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// Puffergröße mit etwas Spielraum
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Ob spezielle Token (BOS: Begin of Sequence etc.) am Anfang hinzugefügt werden sollen
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">bool&lt;/span> &lt;span class="n">add_special&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Zeichenfolge in ein Array von Token-IDs umwandeln
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">n_tokens&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_tokenize&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="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="p">.&lt;/span>&lt;span class="n">c_str&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="p">.&lt;/span>&lt;span class="n">length&lt;/span>&lt;span class="p">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">tokens_list&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">tokens_list&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">add_special&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">false&lt;/span> &lt;span class="c1">// parse_special
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&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">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n_tokens&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Logik für Neuallokation und Wiederholung erforderlich, wenn der Puffer nicht ausreicht (hier zur Vereinfachung weggelassen)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Failed to tokenize prompt&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">1&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 class="n">tokens_list&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">resize&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n_tokens&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="54-inferenzschleife-und-sampling">5.4 Inferenzschleife und Sampling
&lt;/h3>&lt;p>Wir erstellen eine Schleife, in der Tokens in das Modell eingespeist werden, die Wahrscheinlichkeitsverteilung (Logits) für das nächste Token abgerufen wird, und dann durch Sampling das nächste Token bestimmt wird.&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;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;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;span class="lnt">62
&lt;/span>&lt;span class="lnt">63
&lt;/span>&lt;span class="lnt">64
&lt;/span>&lt;span class="lnt">65
&lt;/span>&lt;span class="lnt">66
&lt;/span>&lt;span class="lnt">67
&lt;/span>&lt;span class="lnt">68
&lt;/span>&lt;span class="lnt">69
&lt;/span>&lt;span class="lnt">70
&lt;/span>&lt;span class="lnt">71
&lt;/span>&lt;span class="lnt">72
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Maximale Anzahl der zu generierenden Tokens
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">max_gen_tokens&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>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Struktur für die Batch-Evaluierung initialisieren
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_batch&lt;/span> &lt;span class="n">batch&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_batch_init&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">512&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&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">// Prompt-Tokens zum Batch hinzufügen
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">size_t&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">tokens_list&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">();&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_batch_add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">batch&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">tokens_list&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="p">},&lt;/span> &lt;span class="nb">false&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 class="c1">// So einstellen, dass Logits (Vorhersageergebnisse) nur für das letzte Token des Prompts ausgegeben werden
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">batch&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">logits&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">batch&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">n_tokens&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">true&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">// Erste Evaluierung (Modell mit Prompt füttern)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">llama_decode&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ctx&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">batch&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;llama_decode() failed&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">1&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="kt">int&lt;/span> &lt;span class="n">n_cur&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">batch&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">n_tokens&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// Aktuelle Kontextlänge
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">n_decode&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&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">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">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>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Sampler-Kontext initialisieren (Einstellungen wie Temperature, Top-K, Top-P etc.)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_sampler&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">smpl&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_sampler_chain_init&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">llama_sampler_chain_default_params&lt;/span>&lt;span class="p">());&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_sampler_chain_add_top_k&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">smpl&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">40&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_sampler_chain_add_top_p&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">smpl&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">0.9f&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_sampler_chain_add_temp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">smpl&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">0.7f&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_sampler_chain_add_dist&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">smpl&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1234&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// Seed-Wert
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n_decode&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">max_gen_tokens&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 1. Sampling: Vorhersage des nächsten Tokens basierend auf dem aktuellen Kontext
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_token&lt;/span> &lt;span class="n">new_token_id&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_sampler_sample&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">smpl&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">ctx&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">-&lt;/span>&lt;span class="mi">1&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">// 2. Wenn das Token EOS (End of Sequence) ist, Schleife beenden
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">llama_token_is_eog&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">new_token_id&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">break&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">// 3. Token in einen String (Text) dekodieren und anzeigen
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">char&lt;/span> &lt;span class="n">buf&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">128&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">n_chars&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_token_to_piece&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">new_token_id&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">buf&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">sizeof&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">buf&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">n_chars&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">string&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">buf&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n_chars&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">flush&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">// 4. Das neu generierte Token als nächsten Batch vorbereiten
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_batch_clear&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">batch&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_batch_add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">batch&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">new_token_id&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n_cur&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="p">},&lt;/span> &lt;span class="nb">true&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">// 5. Modellevaluierung (KV-Cache aktualisieren und nächstes vorhersagen)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">llama_decode&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ctx&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">batch&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cerr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Failed to evaluate&amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">break&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="n">n_cur&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">n_decode&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="mi">1&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="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&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">// Bereinigung
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">llama_sampler_free&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">smpl&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_batch_free&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">batch&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_free&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ctx&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llama_free_model&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 class="n">llama_backend_free&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">return&lt;/span> &lt;span class="mi">0&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;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Dieser Code implementiert eine eigene Inferenzschleife mit der Basis-API von llama.cpp.
Er verwendet die &lt;code>llama_batch&lt;/code>-Struktur zur Verwaltung der Tokengruppen und führt mit &lt;code>llama_decode&lt;/code> einen Forward-Pass (Vorwärtsausbreitung) des neuronalen Netzwerks aus.&lt;/p>
&lt;hr>
&lt;h2 id="6-fortgeschrittenes-anpassungsbeispiel-logit-manipulation-und-penalty-steuerung-mit-c">6. Fortgeschrittenes Anpassungsbeispiel: Logit-Manipulation und Penalty-Steuerung mit C++
&lt;/h2>&lt;p>Wenn Sie nicht nur einfachen Text generieren, sondern eine Ausgabe in einem bestimmten Format (z. B. nur JSON) erzwingen oder die Ausgabe bestimmter verbotener Wörter verhindern möchten, können Sie die &lt;strong>Logits&lt;/strong> vor dem Sampling direkt in C++ manipulieren.&lt;/p>
&lt;p>Sie können das Array der rohen Scores (Werte vor der Umwandlung in Wahrscheinlichkeiten) kurz vor der Ausgabe jedes Tokens durch das Modell abrufen.&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;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Rufen Sie das Array der rohen Logits direkt nach der Inferenz und vor dem Sampling ab
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">float&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">logits&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_get_logits_ith&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ctx&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">batch&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">n_tokens&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="n">n_vocab&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llama_n_vocab&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">// Liste der IDs verbotener Tokens (Beispiel: 1234, 5678)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">llama_token&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">forbidden_tokens&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="mi">1234&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">5678&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">// Setzen Sie die Auftrittswahrscheinlichkeit verbotener Tokens auf 0 (Logit auf minus unendlich)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">llama_token&lt;/span> &lt;span class="nl">bad_tok&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">forbidden_tokens&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">logits&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">bad_tok&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="o">-&lt;/span>&lt;span class="n">INFINITY&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;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Durch die direkte Nutzung der C++-API werden &lt;strong>„Eingriffe im Mikrosekundenbereich pro Inferenzzyklus“&lt;/strong> möglich, die über LangChain oder Python nur schwer zu realisieren wären oder mit großem Overhead verbunden sind.&lt;/p>
&lt;hr>
&lt;h2 id="7-die-geheimnisse-der-leistungsoptimierung-performance-tuning">7. Die Geheimnisse der Leistungsoptimierung (Performance Tuning)
&lt;/h2>&lt;p>Nach Abschluss der C++-Implementierung finden Sie hier einige Kontrollpunkte, um die Geschwindigkeit für den praktischen Einsatz auf das Maximum zu steigern.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Optimierung der Batch-Verarbeitung:&lt;/strong> Bei der gleichzeitigen Verarbeitung von Anfragen mehrerer Benutzer können Sie mehrere Sequenzen in einen &lt;code>llama_batch&lt;/code> aufnehmen und &lt;code>llama_decode&lt;/code> einmalig aufrufen (Continuous Batching). Dies bündelt Speicherzugriffe und kann den Durchsatz drastisch verbessern.&lt;/li>
&lt;li>&lt;strong>Flash Attention aktivieren:&lt;/strong>
Durch Setzen von &lt;code>ctx_params.flash_attn = true;&lt;/code> in den Kontextparametern können Sie die Attention-Berechnung beschleunigen und gleichzeitig den Speicherverbrauch reduzieren. Bei der Arbeit mit langen Kontexten (Zehntausende von Tokens) ist diese Einstellung zwingend erforderlich.&lt;/li>
&lt;li>&lt;strong>NUMA-Unterstützung:&lt;/strong>
In Multi-Socket-Serverumgebungen kann die Speicherzugriffslatenz reduziert werden, indem NUMA vor dem Aufruf von &lt;code>llama_backend_init()&lt;/code> entsprechend konfiguriert wird.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="8-fazit">8. Fazit
&lt;/h2>&lt;p>In diesem Artikel haben wir detailliert alles vom mathematischen Hintergrund von &lt;code>llama.cpp&lt;/code> über die Erklärung seiner Architektur bis hin zur Erstellung einer benutzerdefinierten Inferenz-Engine mithilfe der C++-API behandelt.&lt;/p>
&lt;p>Während das Python-Ökosystem sehr nützlich für Prototyping ist, zeigt die direkte Steuerung des C/C++-basierten &lt;code>llama.cpp&lt;/code> in Produktionsumgebungen, die Deployments auf Edge-Geräten, Integrationen in Spiele und Echtzeitverarbeitung erfordern, ihre überwältigende Stärke.&lt;/p>
&lt;p>Wir laden Sie ein, eigenen C++-Code zu schreiben und den Spaß zu erleben, LLMs in Ihrer lokalen Umgebung frei zu steuern.&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>Referenzlinks&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;a class="link" href="https://github.com/ggerganov/llama.cpp" target="_blank" rel="noopener"
>llama.cpp Official Repository&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://github.com/ggerganov/ggml" target="_blank" rel="noopener"
>ggml - Tensor Library&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://arxiv.org/abs/1706.03762" target="_blank" rel="noopener"
>Attention Is All You Need (Vaswani et al., 2017)&lt;/a>&lt;/li>
&lt;/ul>
&lt;/blockquote></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>