> For the complete documentation index, see [llms.txt](https://unsloth.ai/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://unsloth.ai/docs/de/modelle/tutorials/deepseek-v3-0324-how-to-run-locally.md).

# DeepSeek-V3-0324: Wie man lokal ausführt

Wie man DeepSeek-V3-0324 lokal mit unseren dynamischen Quants ausführt, die die Genauigkeit wiederherstellen

{% hint style="info" %}
Bitte beachten Sie <https://docs.unsloth.ai/basics/deepseek-r1-0528-how-to-run-locally> (Aktualisierung vom 28. Mai 2025) um zu lernen, wie man DeepSeek schneller und effizienter ausführt!
{% endhint %}

DeepSeek legt wieder los! Nach der Veröffentlichung von V3, R1 Zero und R1 im Dezember 2024 und Januar 2025 hat DeepSeek seine Checkpoints / Modelle für V3 aktualisiert und ein März-Update veröffentlicht!

Laut DeepSeek sprang MMLU-Pro um +5,3 % auf 81,2 %. **GPQA +9,3 Prozentpunkte**. AIME + 19,8 % und LiveCodeBench + 10,0 %! Sie stellten einen Plot bereit, der zeigte, wie sie im Vergleich zum vorherigen V3-Checkpoint und anderen Modellen wie GPT 4.5 und Claude Sonnet 3.7 abschnitten. <mark style="background-color:blue;">**Aber wie führen wir ein Modell mit 671 Milliarden Parametern lokal aus?**</mark>

<table data-full-width="true"><thead><tr><th>MoE-Bits</th><th>Typ</th><th>Festplattengröße</th><th>Genauigkeit</th><th>Link</th><th>Details</th></tr></thead><tbody><tr><td>1,78 Bit</td><td>IQ1_S</td><td><strong>173GB</strong></td><td>Okay</td><td><a href="https://huggingface.co/unsloth/DeepSeek-V3-0324-GGUF/tree/main/UD-IQ1_S">Link</a></td><td>2,06/1,56 Bit</td></tr><tr><td>1,93 Bit</td><td>IQ1_M</td><td><strong>183 GB</strong></td><td>Mittel</td><td><a href="https://huggingface.co/unsloth/DeepSeek-V3-0324-GGUF/tree/main/UD-IQ1_M">Link</a></td><td>2.5/2.06/1.56</td></tr><tr><td>2,42 Bit</td><td>IQ2_XXS</td><td><strong>203GB</strong></td><td><mark style="background-color:blue;"><strong>Empfohlen</strong></mark></td><td><a href="https://huggingface.co/unsloth/DeepSeek-V3-0324-GGUF/tree/main/UD-IQ2_XXS">Link</a></td><td>2,5/2,06 Bit</td></tr><tr><td>2,71 Bit</td><td>Q2_K_XL</td><td><strong>231GB</strong></td><td><mark style="background-color:purple;"><strong>Empfohlen</strong></mark></td><td><a href="https://huggingface.co/unsloth/DeepSeek-V3-0324-GGUF/tree/main/UD-Q2_K_XL">Link</a></td><td>3,5/2,5 Bit</td></tr><tr><td>3,5 Bit</td><td>Q3_K_XL</td><td><strong>320GB</strong></td><td>Großartig</td><td><a href="https://huggingface.co/unsloth/DeepSeek-V3-0324-GGUF/tree/main/UD-Q3_K_XL">Link</a></td><td>4,5/3,5 Bit</td></tr><tr><td>4,5 Bit</td><td>Q4_K_XL</td><td><strong>406GB</strong></td><td>Am besten</td><td><a href="https://huggingface.co/unsloth/DeepSeek-V3-0324-GGUF/tree/main/UD-Q4_K_XL">Link</a></td><td>5,5/4,5 Bit</td></tr></tbody></table>

{% hint style="success" %}
DeepSeek V3s ursprünglicher Upload liegt in float8 vor und benötigt 715GB. Mit Q4\_K\_M halbiert sich die Dateigröße auf etwa 404GB, und unsere dynamische 1,78-Bit-Quantisierung passt in etwa 151GB. **Wir empfehlen, unsere 2,7-Bit-Quantisierung zu verwenden, um Größe und Genauigkeit auszubalancieren! Die 2,4-Bit-Version funktioniert ebenfalls gut!**
{% endhint %}

## :gear: Offiziell empfohlene Einstellungen

Laut [DeepSeek](https://huggingface.co/deepseek-ai/DeepSeek-V3-0324), dies sind die empfohlenen Einstellungen für die Inferenz:

* <mark style="background-color:blue;">**Temperatur von 0,3**</mark> (Vielleicht 0,0 für Programmierung, da [hier zu sehen](https://api-docs.deepseek.com/quick_start/parameter_settings))
* Min\_P von 0,00 (optional, aber 0,01 funktioniert gut, der Standard von llama.cpp ist 0,1)
* Chat-Vorlage: `<｜User｜>Erstelle ein einfaches spielbares Flappy-Bird-Spiel in Python. Platziere das fertige Spiel in einem Markdown-Abschnitt.<｜Assistant｜>`
* Ein BOS-Token von `<｜begin▁of▁sentence｜>` wird während der Tokenisierung automatisch hinzugefügt (NICHT manuell hinzufügen!)
* DeepSeek erwähnte die Verwendung eines <mark style="background-color:green;">**System-Prompts**</mark> ebenfalls (optional) - es ist auf Chinesisch: `Dieser Assistent ist DeepSeek Chat, erschaffen von DeepSeek.\nHeute ist Montag, der 24. März.` was übersetzt wird als: `Der Assistent ist DeepSeek Chat, erstellt von DeepSeek.\nHeute ist Montag, der 24. März.`
* <mark style="background-color:orange;">**Für die KV-Cache-Quantisierung verwende 8 Bit, NICHT 4 Bit – wir haben festgestellt, dass es deutlich schlechter abschneidet.**</mark>

## 📖 Tutorial: So führst du DeepSeek-V3 in llama.cpp aus

1. Holen Sie sich die neueste `llama.cpp` auf [hier auf GitHub](https://github.com/ggml-org/llama.cpp). Sie können auch die folgenden Build-Anweisungen befolgen. Ändern Sie `-DGGML_CUDA=ON` zu `-DGGML_CUDA=OFF` wenn Sie keine GPU haben oder nur CPU-Inferenz möchten. **Für Apple-Mac-/Metal-Geräte**, setzen Sie `-DGGML_CUDA=OFF` und fahren Sie dann wie gewohnt fort – Metal-Unterstützung ist standardmäßig aktiviert.

{% hint style="warning" %}
HINWEIS: Die Verwendung von `-DGGML_CUDA=ON` für GPUs kann 5 Minuten zum Kompilieren benötigen. Die CPU benötigt nur 1 Minute zum Kompilieren. Vielleicht interessieren dich die vorkompilierten Binärdateien von llama.cpp.
{% endhint %}

```bash
apt-get update
apt-get install pciutils build-essential cmake curl libcurl4-openssl-dev -y
git clone https://github.com/ggml-org/llama.cpp
cmake llama.cpp -B llama.cpp/build \\
    -DBUILD_SHARED_LIBS=OFF -DGGML_CUDA=ON -DLLAMA_CURL=ON
cmake --build llama.cpp/build --config Release -j --clean-first --target llama-quantize llama-cli llama-gguf-split
cp llama.cpp/build/bin/llama-* llama.cpp
```

2. Lade das Modell über (nach der Installation von `pip install huggingface_hub hf_transfer` ). Sie können `UD-IQ1_S`(dynamische 1,78-Bit-Quantisierung) oder andere quantisierte Versionen wie `Q4_K_M` . <mark style="background-color:green;">**Ich empfehle die Verwendung unserer dynamischen 2,7-Bit-Quantisierung**</mark><mark style="background-color:green;">**&#x20;**</mark><mark style="background-color:green;">**`UD-Q2_K_XL`**</mark><mark style="background-color:green;">**&#x20;**</mark><mark style="background-color:green;">**zu verwenden, um Größe und Genauigkeit auszubalancieren**</mark>. Weitere Versionen unter: <https://huggingface.co/unsloth/DeepSeek-V3-0324-GGUF>

{% code overflow="wrap" %}

```python
# !pip install huggingface_hub hf_transfer
import os
os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "1"
from huggingface_hub import snapshot_download
snapshot_download(
    repo_id = "unsloth/DeepSeek-V3-0324-GGUF-UD",
    local_dir = "unsloth/DeepSeek-V3-0324-GGUF-UD",
    allow_patterns = ["*UD-Q2_K_XL*"], # Dynamische 2,7-Bit (230GB) Verwende "*UD-IQ_S*" für dynamische 1,78-Bit (151GB)
)
```

{% endcode %}

3. Führe den Flappy-Bird-Test von Unsloth aus, wie in unserer 1,58-Bit-dynamischen Quantisierung für DeepSeek R1 beschrieben.
4. Bearbeiten `--threads 32` für die Anzahl der CPU-Threads, `--ctx-size 16384` für die Kontextlänge, `--n-gpu-layers 2` für GPU-Offloading auf wie viele Layer. Versuche, ihn anzupassen, wenn deiner GPU der Speicher ausgeht. Entferne ihn auch, wenn du nur CPU-Inferenz hast.

<pre class="language-bash" data-overflow="wrap"><code class="lang-bash">./llama.cpp/llama-cli \\
    --model unsloth/DeepSeek-V3-0324-GGUF-UD/blob/main/UD-Q2_K_XL/DeepSeek-V3-0324-UD-Q2_K_XL-00001-of-00006.gguf \\
    <a data-footnote-ref href="#user-content-fn-1">--cache-type-k q8_0 </a>\\
    <a data-footnote-ref href="#user-content-fn-2">--threads 20</a> \\
    <a data-footnote-ref href="#user-content-fn-3">--n-gpu-layers 2</a> \\
    -no-cnv \\
    --prio 3 \\
    --temp 0.3 \\
    --min-p 0.01 \\
    <a data-footnote-ref href="#user-content-fn-4">--ctx-size 4096</a> \\
    --seed 3407 \\
    --prompt "&#x3C;｜User｜>Erstellen Sie ein Flappy-Bird-Spiel in Python. Sie müssen Folgendes einbauen:\n1. Sie müssen pygame verwenden.\n2. Die Hintergrundfarbe sollte zufällig gewählt werden und hell sein. Beginnen Sie mit einer hellblauen Farbe.\n3. Wenn die LEERTASTE mehrmals gedrückt wird, beschleunigt sich der Vogel.\n4. Die Form des Vogels sollte zufällig als Quadrat, Kreis oder Dreieck gewählt werden. Die Farbe sollte zufällig als dunkle Farbe gewählt werden.\n5. Platzieren Sie unten etwas Land, das zufällig dunkelbraun oder gelb gefärbt ist.\n6. Zeigen Sie oben rechts einen Punktestand an. Erhöhen Sie ihn, wenn Sie Rohre passieren und sie nicht berühren.\n7. Erstellen Sie zufällig verteilte Rohre mit genügend Abstand. Färben Sie sie zufällig dunkelgrün, hellbraun oder in einem dunklen Grauton.\n8. Wenn Sie verlieren, zeigen Sie den Bestwert an. Platzieren Sie den Text innerhalb des Bildschirms. Mit q oder Esc wird das Spiel beendet. Ein Neustart erfolgt durch erneutes Drücken von LEERTASTE.\nDas fertige Spiel sollte sich innerhalb eines Markdown-Abschnitts in Python befinden. Überprüfen Sie Ihren Code vor dem finalen Markdown-Abschnitt auf Fehler und beheben Sie diese.&#x3C;｜Assistant｜>"
</code></pre>

<details>

<summary>Wenn wir das Obige ausführen, erhalten wir 2 sehr unterschiedliche Ergebnisse.<br><br><strong>Standard-2-Bit-Version:</strong> Klicken, um das Ergebnis anzuzeigen <em><mark style="color:rot;"><strong>(Anfallwarnung!)</strong></mark></em><br><strong>Dynamische 2-Bit-Version:</strong> Siehe das Ergebnis unten:</summary>

<img src="https://797013937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-5ab85f63c9fb12f0ce701dd3cfd540aa1503a636%2FOld.gif?alt=media" alt="" data-size="original">

Standard-2-Bit. Scheitert mit Hintergrund, scheitert bei Kollision

</details>

<div align="center"><figure><img src="https://797013937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-97735d09e3d399cf74f8e7112eef8ca56b0e10e9%2FNew.gif?alt=media" alt="" width="240"><figcaption><p>Dynamische 2-Bit. Erzeugt erfolgreich ein spielbares Spiel.</p></figcaption></figure></div>

5. Wie DeepSeek-R1 hat V3 61 Schichten. Zum Beispiel kannst du bei einer 24GB-GPU oder 80GB-GPU nach dem Abrunden mit folgendem Offloading rechnen (um 1 reduzieren, wenn es aus dem Speicher läuft):

| Quant    | Dateigröße | 24-GB-GPU | 80-GB-GPU | 2x80-GB-GPU |
| -------- | ---------- | --------- | --------- | ----------- |
| 1,73 Bit | 173GB      | 5         | 25        | 56          |
| 2,22 Bit | 183 GB     | 4         | 22        | 49          |
| 2,51 Bit | 212 GB     | 2         | 19        | 32          |

### Ausführung auf Mac-/Apple-Geräten

Bei Apple-Metal-Geräten sei vorsichtig mit `--n-gpu-layers`. Wenn du feststellst, dass die Maschine aus dem Speicher läuft, reduziere ihn. Auf einer Maschine mit 128GB Unified Memory solltest du etwa 59 Layer auslagern können.

```bash
./llama.cpp/llama-cli \\
    --model DeepSeek-R1-GGUF/DeepSeek-V3-0324-UD-IQ1_S/DeepSeek-V3-0324-UD-IQ1_S-00001-of-00003.gguf \\
    --cache-type-k q4_0 \\
    --threads 16 \\
    --prio 2 \\
    --temp 0.6 \
    --ctx-size 8192 \\
    --seed 3407 \\
    --n-gpu-layers 59 \\
    -no-cnv \\
    --prompt "<｜User｜>Create a Flappy Bird game in Python.<｜Assistant｜>"
```

## :8ball: Heptagon-Test

Wir testen unsere dynamischen Quants auch über [r/Localllama](https://www.reddit.com/r/LocalLLaMA/comments/1j7r47l/i_just_made_an_animation_of_a_ball_bouncing/) das das Modell darauf testet, eine einfache Physik-Engine zu erstellen, um Bälle zu simulieren, die in einer sich bewegenden, geschlossenen Heptagonform rotieren.

<figure><img src="https://797013937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-1371de5a93c6c5b0e43e8bb51980d84554b199f4%2Fsnapshot.jpg?alt=media" alt="" width="563"><figcaption><p>Das Ziel ist, das Heptagon rotieren zu lassen, und die Bälle im Heptagon sollten sich bewegen.</p></figcaption></figure>

{% code overflow="wrap" %}

```bash
./llama.cpp/llama-cli \\
    --model unsloth/DeepSeek-V3-0324-GGUF-UD/blob/main/UD-Q2_K_XL/DeepSeek-V3-0324-UD-Q2_K_XL-00001-of-00006.gguf \\
    --cache-type-k q8_0 \\
    --threads 20 \\
    --n-gpu-layers 2 \\
    -no-cnv \\
    --prio 3 \\
    --temp 0.3 \\
    --min-p 0.01 \\
    --ctx-size 4096 \\
    --seed 3407 \\
    --prompt "<｜User｜>Schreibe ein Python-Programm, das 20 Bälle zeigt, die in einem rotierenden Heptagon herumhüpfen:\n- Alle Bälle haben den gleichen Radius.\n- Alle Bälle haben eine Nummer von 1 bis 20 darauf.\n- Alle Bälle fallen beim Start aus dem Zentrum des Heptagons heraus.\n- Die Farben sind: #f8b862, #f6ad49, #f39800, #f08300, #ec6d51, #ee7948, #ed6d3d, #ec6800, #ec6800, #ee7800, #eb6238, #ea5506, #ea5506, #eb6101, #e49e61, #e45e32, #e17b34, #dd7a56, #db8449, #d66a35\n- Die Bälle sollen von Schwerkraft und Reibung beeinflusst werden und sie müssen realistisch von den rotierenden Wänden abprallen. Es sollte auch Kollisionen zwischen den Bällen geben.\n- Das Material aller Bälle bestimmt, dass ihre Aufprallhöhe nicht den Radius des Heptagons überschreitet, aber höher als der Ballradius ist.\n- Alle Bälle rotieren mit Reibung, die Zahlen auf den Bällen können verwendet werden, um den Spin des Balls anzuzeigen.\n- Das Heptagon rotiert um sein Zentrum, und die Rotationsgeschwindigkeit beträgt 360 Grad pro 5 Sekunden.\n- Die Größe des Heptagons sollte groß genug sein, um alle Bälle aufzunehmen.\n- Verwende nicht die pygame-Bibliothek; implementiere Kollisionsdetektionsalgorithmen und Kollisionsreaktion usw. selbst. Die folgenden Python-Bibliotheken sind erlaubt: tkinter, math, numpy, dataclasses, typing, sys.\n- Der gesamte Code sollte in eine einzige Python-Datei gelegt werden.<｜Assistant｜>"
```

{% endcode %}

<table data-view="cards"><thead><tr><th></th><th data-type="files"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td>Nicht-dynamisches 2-Bit. Scheitert - <mark style="background-color:red;">ANFALLWARNUNG</mark> wieder!</td><td><a href="https://797013937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-0e0d101cc282b869a97fc679da5a9e98141c6f62%2Funsloth-q2_k_rotate.txt?alt=media">unsloth-q2_k_rotate.txt</a></td><td><a href="https://797013937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-d2579e8d1145572548ed69b0e335925f47130ba3%2FInShot_20250325_185636426.gif?alt=media">InShot_20250325_185636426.gif</a></td></tr><tr><td>Dynamische 2-Bit. Löst das Heptagon-Rätsel tatsächlich korrekt!!</td><td><a href="https://797013937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-96202dad58c0d0004cdb51408332ac78b425138f%2Funsloth-q2_k_xl_rotate.txt?alt=media">unsloth-q2_k_xl_rotate.txt</a></td><td><a href="https://797013937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-669f5b08b6bf220a38dce445d4830fcd80d52be3%2FInShot_20250325_181710554.gif?alt=media">InShot_20250325_181710554.gif</a></td></tr><tr><td>Ursprüngliches float8</td><td><a href="https://797013937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-902430fe71d14f19cd31d3fe271f9a636e91304e%2Ffp8-heptagon.txt?alt=media">fp8-heptagon.txt</a></td><td><a href="https://797013937-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-4501a6aef616d02057b89e96baa9c1d5ed57666f%2FInShot_20250325_181423756.gif?alt=media">InShot_20250325_181423756.gif</a></td></tr></tbody></table>

Die dynamische 2,7-Bit-Quantisierung, die nur 230GB groß ist, schafft es tatsächlich, das Heptagon-Rätsel zu lösen! Die vollständige Ausgabe für alle 3 Versionen (einschließlich des vollständigen fp8) ist unten:

<details>

<summary>Dynamischer 2-Bit-Heptagon-Code</summary>

```python
import tkinter as tk
import math
import numpy as np
from dataclasses import dataclass
from typing import List, Tuple, Optional

# Konstanten
HEPTAGON_RADIUS = 300
BALL_RADIUS = 20
GRAVITY = 0.2
FRICTION = 0.99
BOUNCE_FACTOR = 0.8
ROTATION_SPEED = 360 / 5  # Grad pro Sekunde
SPIN_FRICTION = 0.98
BALL_COLORS = [
    "#f8b862", "#f6ad49", "#f39800", "#f08300", "#ec6d51",
    "#ee7948", "#ed6d3d", "#ec6800", "#ec6800", "#ee7800",
    "#eb6238", "#ea5506", "#ea5506", "#eb6101", "#e49e61",
    "#e45e32", "#e17b34", "#dd7a56", "#db8449", "#d66a35"
]

@dataclass
class Ball:
    x: float
    y: float
    vx: float
    vy: float
    number: int
    spin: float = 0.0
    color: str = "#000000"

@dataclass
class Wall:
    x1: float
    y1: float
    x2: float
    y2: float

class BouncingBalls:
    def __init__(self, root):
        self.root = root
        self.canvas = tk.Canvas(root, width=800, height=800, bg="white")
        self.canvas.pack()
        self.balls: List[Ball] = []
        self.walls: List[Wall] = []
        self.heptagon_angle = 0
        self.last_time = 0
        
        self.setup_balls()
        self.setup_heptagon()
        
        self.root.after(16, self.update)
        self.root.bind("<space>", self.reset_balls)
    
    def setup_balls(self):
        for i in range(20):
            ball = Ball(
                x=400,
                y=400,
                vx=np.random.uniform(-5, 5),
                vy=np.random.uniform(-5, 5),
                number=i+1,
                color=BALL_COLORS[i]
            )
            self.balls.append(ball)
    
    def setup_heptagon(self):
        # Anfangswände des Heptagons erstellen
        self.update_heptagon_walls(0)
    
    def update_heptagon_walls(self, angle):
        self.walls = []
        center_x, center_y = 400, 400
        angle_rad = math.radians(angle)
        
        for i in range(7):
            angle1 = angle_rad + 2 * math.pi * i / 7
            angle2 = angle_rad + 2 * math.pi * (i + 1) / 7
            
            x1 = center_x + HEPTAGON_RADIUS * math.cos(angle1)
            y1 = center_y + HEPTAGON_RADIUS * math.sin(angle1)
            x2 = center_x + HEPTAGON_RADIUS * math.cos(angle2)
            y2 = center_y + HEPTAGON_RADIUS * math.sin(angle2)
            
            self.walls.append(Wall(x1, y1, x2, y2))
    
    def reset_balls(self, event=None):
        for ball in self.balls:
            ball.x = 400
            ball.y = 400
            ball.vx = np.random.uniform(-5, 5)
            ball.vy = np.random.uniform(-5, 5)
            ball.spin = np.random.uniform(-5, 5)
    
    def update(self):
        current_time = self.root.after_idle(self.root.after, 16, self.update)
        if self.last_time == 0:
            self.last_time = current_time
            return
        
        # Delta-Zeit berechnen (ungefähr)
        dt = 0.016  # Angenommen ~60 FPS
        
        # Heptagon-Rotation aktualisieren
        self.heptagon_angle += ROTATION_SPEED * dt
        self.update_heptagon_walls(self.heptagon_angle)
        
        # Bälle aktualisieren
        for ball in self.balls:
            # Schwerkraft anwenden
            ball.vy += GRAVITY
            
            # Reibung anwenden
            ball.vx *= FRICTION
            ball.vy *= FRICTION
            ball.spin *= SPIN_FRICTION
            
            # Ball bewegen
            ball.x += ball.vx
            ball.y += ball.vy
            
            # Kollisionen mit Wänden prüfen
            self.check_wall_collisions(ball)
            
            # Kollisionen mit anderen Bällen prüfen
            for other in self.balls:
                if other.number != ball.number:
                    self.check_ball_collision(ball, other)
        
        # Alles zeichnen
        self.draw()
    
    def check_wall_collisions(self, ball):
        for wall in self.walls:
            # Nächsten Punkt auf dem Wandsegment zum Ball finden
            closest = self.closest_point_on_segment(
                wall.x1, wall.y1, wall.x2, wall.y2, ball.x, ball.y
            )
            
            # Abstand zur Wand berechnen
            dx = ball.x - closest[0]
            dy = ball.y - closest[1]
            distance = math.sqrt(dx*dx + dy*dy)
            
            if distance < BALL_RADIUS:
                # Kollision erkannt
                # Normalenvektor berechnen
                nx = dx / distance
                ny = dy / distance
                
                # Relative Geschwindigkeit entlang der Normale berechnen
                v_rel = ball.vx * nx + ball.vy * ny
                
                if v_rel < 0:  # Bewegt sich auf die Wand zu
                    # Impuls berechnen
                    j = -(1 + BOUNCE_FACTOR) * v_rel
                    
                    # Impuls anwenden
                    ball.vx += j * nx
                    ball.vy += j * ny
                    
                    # Etwas Spin basierend auf der Kollision hinzufügen
                    ball.spin += (ball.vx * ny - ball.vy * nx) * 0.1
                    
                    # Ball aus der Kollision herausbewegen
                    penetration = BALL_RADIUS - distance
                    ball.x += penetration * nx
                    ball.y += penetration * ny
    
    def check_ball_collision(self, ball1, ball2):
        dx = ball2.x - ball1.x
        dy = ball2.y - ball1.y
        distance = math.sqrt(dx*dx + dy*dy)
        
        if distance < 2 * BALL_RADIUS:
            # Kollision erkannt
            nx = dx / distance
            ny = dy / distance
            
            # Relative Geschwindigkeit berechnen
            v_rel_x = ball2.vx - ball1.vx
            v_rel_y = ball2.vy - ball1.vy
            v_rel = v_rel_x * nx + v_rel_y * ny
            
            if v_rel < 0:  # Bewegen sich aufeinander zu
                # Impuls berechnen
                j = -(1 + BOUNCE_FACTOR) * v_rel / 2
                
                # Impulse anwenden
                ball1.vx -= j * nx
                ball1.vy -= j * ny
                ball2.vx += j * nx
                ball2.vy += j * ny
                
                # Etwas Spin basierend auf der Kollision hinzufügen
                ball1.spin += (ball1.vx * ny - ball1.vy * nx) * 0.05
                ball2.spin += (ball2.vx * ny - ball2.vy * nx) * 0.05
                
                # Bälle voneinander wegbewegen
                penetration = 2 * BALL_RADIUS - distance
                ball1.x -= penetration * nx * 0.5
                ball1.y -= penetration * ny * 0.5
                ball2.x += penetration * nx * 0.5
                ball2.y += penetration * ny * 0.5
    
    @staticmethod
    def closest_point_on_segment(x1, y1, x2, y2, x, y):
        # Vektor vom Punkt zum Segmentanfang
        dx = x - x1
        dy = y - y1
        
        # Segmentvektor
        sx = x2 - x1
        sy = y2 - y1
        
        # Projektion des Punkts auf das Segment
        dot = dx * sx + dy * sy
        len_sq = sx * sx + sy * sy
        param = dot / len_sq if len_sq != 0 else -1
        
        if param < 0:
            return x1, y1
        elif param > 1:
            return x2, y2
        else:
            return x1 + param * sx, y1 + param * sy
    
    def draw(self):
        self.canvas.delete("all")
        
        # Heptagon zeichnen
        points = []
        for wall in self.walls:
            points.extend([wall.x1, wall.y1])
        self.canvas.create_polygon(points, fill="", outline="black", width=2)
        
        # Bälle zeichnen
        for ball in self.balls:
            # Ball zeichnen
            self.canvas.create_oval(
                ball.x - BALL_RADIUS, ball.y - BALL_RADIUS,
                ball.x + BALL_RADIUS, ball.y + BALL_RADIUS,
                fill=ball.color, outline="black"
            )
            
            # Nummer mit anhand des Spins basierter Rotation zeichnen
            angle = ball.spin * 10  # Spin für visuelle Wirkung skalieren
            self.canvas.create_text(
                ball.x, ball.y,
                text=str(ball.number),
                font=("Arial", 12, "bold"),
                angle=angle
            )

if __name__ == "__main__":
    root = tk.Tk()
    root.title("Hüpfende Bälle im rotierenden Heptagon")
    app = BouncingBalls(root)
    root.mainloop()
```

</details>

<details>

<summary>Nicht-dynamischer 2-Bit-Heptagon-Code</summary>

```python
import tkinter as tk
import math
import random
from dataclasses import dataclass
from typing import List, Tuple, Optional
import sys

# Konstanten
WIDTH, HEIGHT = 800, 800
HEPTAGON_RADIUS = 300
BALL_RADIUS = 15
GRAVITY = 0.5
FRICTION = 0.999
ELASTICITY = 0.8
ROTATION_SPEED = 2 * math.pi / 5  # 360 Grad pro 5 Sekunden
SPIN_DECAY = 0.99

# Farben für die Bälle
BALL_COLORS = [
    "#f8b862", "#f6ad49", "#f39800", "#f08300", "#ec6d51",
    "#ee7948", "#ed6d3d", "#ec6800", "#ec6800", "#ee7800",
    "#eb6238", "#ea5506", "#ea5506", "#eb6101", "#e49e61",
    "#e45e32", "#e17b34", "#dd7a56", "#db8449", "#d66a35"
]

@dataclass
class Ball:
    x: float
    y: float
    vx: float
    vy: float
    radius: float
    color: str
    number: int
    spin: float = 0.0

@dataclass
class Heptagon:
    center_x: float
    center_y: float
    radius: float
    angle: float = 0.0

class BouncingBalls:
    def __init__(self, root):
        self.root = root
        self.canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, bg="white")
        self.canvas.pack()
        
        self.heptagon = Heptagon(WIDTH//2, HEIGHT//2, HEPTAGON_RADIUS)
        self.balls = []
        self.setup_balls()
        
        self.root.after(0, self.update)
        self.root.mainloop()
    
    def setup_balls(self):
        center_x, center_y = WIDTH//2, HEIGHT//2
        for i in range(20):
            self.balls.append(Ball(
                x=center_x,
                y=center_y,
                vx=0,
                vy=0,
                radius=BALL_RADIUS,
                color=BALL_COLORS[i],
                number=i+1,
                spin=0
            ))
    
    def update(self):
        self.canvas.delete("all")
        
        # Heptagon-Winkel aktualisieren
        self.heptagon.angle += ROTATION_SPEED / 60  # Angenommen 60 FPS
        
        # Heptagon zeichnen
        self.draw_heptagon()
        
        # Bälle aktualisieren und zeichnen
        for ball in self.balls:
            # Schwerkraft anwenden
            ball.vy += GRAVITY
            
            # Position aktualisieren
            ball.x += ball.vx
            ball.y += ball.vy
            
            # Reibung anwenden
            ball.vx *= FRICTION
            ball.vy *= FRICTION
            
            # Drehimpuls-Abklingung anwenden
            ball.spin *= SPIN_DECAY
            
            # Kollision mit den Heptagon-Wänden prüfen
            self.check_heptagon_collision(ball)
            
            # Kollision mit anderen Bällen prüfen
            for other in self.balls:
                if other != ball:
                    if self.check_ball_collision(ball, other):
                        self.resolve_ball_collision(ball, other)
            
            # Den Ball zeichnen
            self.draw_ball(ball)
        
        self.root.after(16, self.update)  # ~60 FPS
    
    def draw_heptagon(self):
        center_x, center_y = self.heptagon.center_x, self.heptagon.center_y
        points = []
        for i in range(7):
            angle = self.heptagon.angle + i * 2 * math.pi / 7
            x = center_x + self.heptagon.radius * math.cos(angle)
            y = center_y + self.heptagon.radius * math.sin(angle)
            points.append((x, y))
        
        # Heptagon zeichnen
        self.canvas.create_polygon(
            [points[0], points[1], points[2], points[3], 
             points[4], points[5], points[6]],
            outline="black", fill="", width=2
        )
    
    def draw_ball(self, ball):
        self.canvas.create_oval(
            ball.x - ball.radius,
            ball.y - ball.radius,
            ball.x + ball.radius,
            ball.y + ball.radius,
            fill=ball.color,
            outline="black"
        )
        
        # Die Zahl zeichnen
        self.canvas.create_text(
            ball.x, ball.y,
            text=str(ball.number),
            fill="black"
        )
    
    def check_heptagon_collision(self, ball):
        center_x, center_y = WIDTH//2, HEIGHT//2
        
        # Abstand vom Zentrum prüfen
        dx = ball.x - center_x
        dy = ball.y - center_y
        dist = math.sqrt(dx**2 + dy**2)
        
        if dist + ball.radius > self.heptagon.radius:
            # Den Normalenvektor vom Zentrum zum Ball bestimmen
            angle = math.atan2(dy, dx)
            normal_x = math.cos(angle)
            normal_y = math.sin(angle)
            
            # Ball zurück ins Heptagon bewegen
            overlap = (dist + ball.radius) - self.heptagon.radius
            ball.x -= overlap * normal_x
            ball.y -= overlap * normal_y
            
            # Geschwindigkeit reflektieren
            dot_product = ball.vx * normal_x + ball.vy * normal_y
            ball.vx -= 2 * dot_product * normal_x * ELASTICITY
            ball.vy -= 2 * dot_product * normal_y * ELASTICITY
    
    def check_ball_collision(self, ball1, ball2):
        dx = ball2.x - ball1.x
        dy = ball2.y - ball1.y
        distance = math.sqrt(dx**2 + dy**2)
        return distance < (ball1.radius + ball2.radius)
    
    def resolve_ball_collision(self, ball1, ball2):
        dx = ball2.x - ball1.x
        dy = ball2.y - ball1.y
        distance = math.sqrt(dx**2 + dy**2)
        
        # Normalenvektor
        nx = dx / distance
        ny = dy / distance
        
        # Relative Geschwindigkeit
        dvx = ball2.vx - ball1.vx
        dvy = ball2.vy - ball1.vy
        
        # Impuls berechnen
        impulse = 2 * (dvx * nx + dvy * ny) / 2
        impulse *= ELASTICITY
        
        # Impuls anwenden
        ball1.vx -= impulse * nx
        ball1.vy -= impulse * ny
        ball2.vx += impulse * nx
        ball2.vy += impulse * ny
        
        # Die Bälle trennen, um ein Festkleben zu verhindern
        overlap = (ball1.radius + ball2.radius) - distance
        ball1.x -= overlap * nx / 2
        ball1.y -= overlap * ny / 2
        ball2.x += overlap * nx / 2
        ball2.y += overlap * ny / 2
    
    def run(self):
        self.root.mainloop()

if __name__ == "__main__":
    root = tk.Tk()
    root.title("Springende Bälle in einem rotierenden Heptagon")
    app = BouncingBalls(root)
    app.run()
```

</details>

<details>

<summary>Float8-Heptagon-Code</summary>

```python
import tkinter as tk
import math
import numpy as np
from dataclasses import dataclass
from typing import List, Tuple, Optional

# Konstanten
WIDTH, HEIGHT = 800, 800
CENTER_X, CENTER_Y = WIDTH // 2, HEIGHT // 2
GRAVITY = 0.2
FRICTION = 0.99
BALL_RADIUS = 15
HEPTAGON_RADIUS = 300
ROTATION_SPEED = 360 / 5  # Grad pro Sekunde
ELASTICITY = 0.8
SPIN_FRICTION = 0.98

# Farben für die Bälle
BALL_COLORS = [
    '#f8b862', '#f6ad49', '#f39800', '#f08300', '#ec6d51',
    '#ee7948', '#ed6d3d', '#ec6800', '#ec6800', '#ee7800',
    '#eb6238', '#ea5506', '#ea5506', '#eb6101', '#e49e61',
    '#e45e32', '#e17b34', '#dd7a56', '#db8449', '#d66a35'
]

@dataclass
class Ball:
    x: float
    y: float
    vx: float
    vy: float
    radius: float
    color: str
    number: int
    spin: float = 0.0

    def move(self):
        self.x += self.vx
        self.y += self.vy
        self.vy += GRAVITY
        self.vx *= FRICTION
        self.vy *= FRICTION
        self.spin *= SPIN_FRICTION

    def collide_with_ball(self, other: 'Ball'):
        dx = other.x - self.x
        dy = other.y - self.y
        distance = math.hypot(dx, dy)
        
        if distance < self.radius + other.radius:
            # Kollisionnormalen berechnen
            nx = dx / distance
            ny = dy / distance
            
            # Relative Geschwindigkeit berechnen
            dvx = other.vx - self.vx
            dvy = other.vy - self.vy
            
            # Impuls berechnen
            impulse = 2 * (dvx * nx + dvy * ny) / (1/self.radius + 1/other.radius)
            
            # Impuls anwenden
            self.vx += impulse * nx / self.radius
            self.vy += impulse * ny / self.radius
            other.vx -= impulse * nx / other.radius
            other.vy -= impulse * ny / other.radius
            
            # Bälle trennen, um Festkleben zu verhindern
            overlap = (self.radius + other.radius - distance) / 2
            self.x -= overlap * nx
            self.y -= overlap * ny
            other.x += overlap * nx
            other.y += overlap * ny
            
            # Etwas Drehung übertragen
            transfer = impulse * 0.01
            self.spin -= transfer
            other.spin += transfer

class HeptagonBounceSimulator:
    def __init__(self, root):
        self.root = root
        self.canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, bg='white')
        self.canvas.pack()
        
        self.balls = self.create_balls()
        self.heptagon_angle = 0
        self.last_time = 0
        self.running = True
        
        self.root.bind('<space>', self.toggle_pause)
        self.root.bind('<Escape>', lambda e: root.destroy())
        
        self.last_time = self.root.after(0, self.update)
    
    def create_balls(self) -> List[Ball]:
        balls = []
        for i in range(20):
            # Alle Bälle mit kleiner zufälliger Geschwindigkeit im Zentrum starten
            angle = np.random.uniform(0, 2 * math.pi)
            speed = np.random.uniform(0.5, 2)
            vx = math.cos(angle) * speed
            vy = math.sin(angle) * speed
            
            balls.append(Ball(
                x=CENTER_X,
                y=CENTER_Y,
                vx=vx,
                vy=vy,
                radius=BALL_RADIUS,
                color=BALL_COLORS[i],
                number=i+1,
                spin=np.random.uniform(-2, 2)
            ))
        return balls
    
    def toggle_pause(self, event):
        self.running = not self.running
        if self.running:
            self.last_time = self.root.after(0, self.update)
    
    def get_heptagon_vertices(self) -> List[Tuple[float, float]]:
        vertices = []
        for i in range(7):
            angle = math.radians(self.heptagon_angle + i * 360 / 7)
            x = CENTER_X + HEPTAGON_RADIUS * math.cos(angle)
            y = CENTER_Y + HEPTAGON_RADIUS * math.sin(angle)
            vertices.append((x, y))
        return vertices
    
    def check_ball_heptagon_collision(self, ball: Ball):
        vertices = self.get_heptagon_vertices()
        closest_dist = float('inf')
        closest_normal = (0, 0)
        closest_edge = None
        
        # Kollision mit jeder Kante des Heptagons prüfen
        for i in range(len(vertices)):
            p1 = vertices[i]
            p2 = vertices[(i + 1) % len(vertices)]
            
            # Vektor von p1 nach p2
            edge_x = p2[0] - p1[0]
            edge_y = p2[1] - p1[1]
            edge_length = math.hypot(edge_x, edge_y)
            
            # Kantenvektor normieren
            edge_x /= edge_length
            edge_y /= edge_length
            
            # Normalenvektor (senkrecht zur Kante, nach innen zeigend)
            nx = -edge_y
            ny = edge_x
            
            # Vektor von p1 zum Ball
            ball_to_p1_x = ball.x - p1[0]
            ball_to_p1_y = ball.y - p1[1]
            
            # Ball auf die Kanten-Normale projizieren
            projection = ball_to_p1_x * nx + ball_to_p1_y * ny
            
            # Wenn die Projektion negativ ist, liegt der Ball außerhalb des Heptagons
            if projection < ball.radius:
                # Den nächstgelegenen Punkt auf der Kante zum Ball finden
                edge_proj = ball_to_p1_x * edge_x + ball_to_p1_y * edge_y
                edge_proj = max(0, min(edge_length, edge_proj))
                closest_x = p1[0] + edge_proj * edge_x
                closest_y = p1[1] + edge_proj * edge_y
                
                # Abstand vom Ball zum nächstgelegenen Punkt auf der Kante
                dist = math.hypot(ball.x - closest_x, ball.y - closest_y)
                
                if dist < closest_dist:
                    closest_dist = dist
                    closest_normal = (nx, ny)
                    closest_edge = (p1, p2)
        
        if closest_dist < ball.radius:
            # Abprallreaktion berechnen
            dot_product = ball.vx * closest_normal[0] + ball.vy * closest_normal[1]
            
            # Abprall mit Elastizität anwenden
            ball.vx -= (1 + ELASTICITY) * dot_product * closest_normal[0]
            ball.vy -= (1 + ELASTICITY) * dot_product * closest_normal[1]
            
            # Etwas Drehung basierend auf dem Aufprall hinzufügen
            edge_vec = (closest_edge[1][0] - closest_edge[0][0], 
                        closest_edge[1][1] - closest_edge[0][1])
            edge_length = math.hypot(edge_vec[0], edge_vec[1])
            if edge_length > 0:
                edge_vec = (edge_vec[0]/edge_length, edge_vec[1]/edge_length)
                # Kreuzprodukt von Geschwindigkeit und Kantenrichtung
                spin_effect = (ball.vx * edge_vec[1] - ball.vy * edge_vec[0]) * 0.1
                ball.spin += spin_effect
            
            # Ball außerhalb des Heptagons bewegen, um Festkleben zu verhindern
            penetration = ball.radius - closest_dist
            ball.x += penetration * closest_normal[0]
            ball.y += penetration * closest_normal[1]
    
    def update(self):
        if not self.running:
            return
        
        # Leinwand löschen
        self.canvas.delete('all')
        
        # Heptagon-Rotation aktualisieren
        self.heptagon_angle += ROTATION_SPEED / 60  # Angenommen ~60 FPS
        
        # Heptagon zeichnen
        vertices = self.get_heptagon_vertices()
        self.canvas.create_polygon(vertices, outline='black', fill='', width=2)
        
        # Bälle aktualisieren und zeichnen
        for i, ball in enumerate(self.balls):
            # Ball bewegen
            ball.move()
            
            # Kollisionen mit dem Heptagon prüfen
            self.check_ball_heptagon_collision(ball)
            
            # Ball zeichnen
            self.canvas.create_oval(
                ball.x - ball.radius, ball.y - ball.radius,
                ball.x + ball.radius, ball.y + ball.radius,
                fill=ball.color, outline='black'
            )
            
            # Nummer mit anhand des Spins basierter Rotation zeichnen
            angle = ball.spin * 10  # Spin für sichtbare Rotation skalieren
            self.canvas.create_text(
                ball.x, ball.y,
                text=str(ball.number),
                font=('Arial', 10, 'bold'),
                angle=angle
            )
        
        # Ball-Ball-Kollisionen prüfen
        for i in range(len(self.balls)):
            for j in range(i + 1, len(self.balls)):
                self.balls[i].collide_with_ball(self.balls[j])
        
        # Nächste Aktualisierung planen
        self.last_time = self.root.after(16, self.update)  # ~60 FPS

if __name__ == '__main__':
    root = tk.Tk()
    root.title('Springende Bälle in einem rotierenden Heptagon')
    simulator = HeptagonBounceSimulator(root)
    root.mainloop()
```

</details>

## :detective: Zusätzliche Erkenntnisse & Tipps

1. Wir haben festgestellt, dass die Verwendung einer niedrigeren KV-Cache-Quantisierung (4 Bit) die Generierungsqualität gemäß empirischen Tests zu verschlechtern scheint – es sind weitere Tests nötig, aber wir empfehlen die Verwendung von `q8_0` Cache-Quantisierung. Das Ziel der Quantisierung ist es, längere Kontextlängen zu unterstützen, da der KV-Cache ziemlich viel Speicher verwendet.
2. Wir haben festgestellt, dass die `down_proj` in diesem Modell extrem empfindlich gegenüber Quantisierung ist. Wir mussten einige unserer dynamischen Quantisierungen, die 2 Bit für `down_proj` verwendeten, neu erstellen, und jetzt verwenden wir 3 Bit als Minimum für all diese Matrizen.
3. Die Verwendung von `llama.cpp` s Flash-Attention-Backend führt zu etwas schnelleren Decodierungsgeschwindigkeiten. Verwenden Sie `-DGGML_CUDA_FA_ALL_QUANTS=ON` beim Kompilieren. Beachten Sie, dass es auch am besten ist, Ihre CUDA-Architektur wie unter <https://developer.nvidia.com/cuda-gpus> festzulegen, um die Kompilierungszeiten zu verkürzen, und sie dann über `-DCMAKE_CUDA_ARCHITECTURES="80"`
4. Die Verwendung eines `min_p=0.01`reicht wahrscheinlich aus. `llama.cpp`ist standardmäßig 0,1, was wahrscheinlich nicht notwendig ist. Da ohnehin eine Temperatur von 0,3 verwendet wird, werden wir höchstwahrscheinlich sehr unwahrscheinlich Tokens mit niedriger Wahrscheinlichkeit sampeln, daher ist das Entfernen sehr unwahrscheinlicher Tokens eine gute Idee. DeepSeek empfiehlt eine Temperatur von 0,0 für Programmieraufgaben.

[^1]: MUSS 8 Bit verwenden - nicht 4 Bit

[^2]: CPU-Threads, die dein Rechner hat

[^3]: Ca. 2 für 24GB GPU. Ca. 18 für 80GB GPU.

[^4]: Kontextlänge


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://unsloth.ai/docs/de/modelle/tutorials/deepseek-v3-0324-how-to-run-locally.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
