# DeepSeek-V3-0324: ローカルで実行する方法

{% hint style="info" %}
をご覧ください <https://docs.unsloth.ai/basics/deepseek-r1-0528-how-to-run-locally> （2025年5月28日更新）DeepSeekをより速く、より効率的に実行する方法を学びましょう！
{% endhint %}

DeepSeekがまた動き出しました！2024年12月と2025年1月にV3、R1 Zero、R1をリリースした後、DeepSeekはV3のチェックポイント／モデルを更新し、3月のアップデートを公開しました！

DeepSeekによると、MMLU-Proは+5.3%上昇して81.2%になりました。 **GPQA +9.3ポイント**。AIMEは+19.8%、LiveCodeBenchは+10.0%！彼らは以前のV3チェックポイントやGPT 4.5、Claude Sonnet 3.7などのモデルと比較したプロットを提供しました。 <mark style="background-color:blue;">**では、6710億パラメータのモデルをどうやってローカルで動かすのでしょうか？**</mark>

<table data-full-width="true"><thead><tr><th>MoE ビット数</th><th>タイプ</th><th>ディスクサイズ</th><th>精度</th><th>リンク</th><th>詳細</th></tr></thead><tbody><tr><td>1.78ビット</td><td>IQ1_S</td><td><strong>173GB</strong></td><td>OK</td><td><a href="https://huggingface.co/unsloth/DeepSeek-V3-0324-GGUF/tree/main/UD-IQ1_S">リンク</a></td><td>2.06/1.56ビット</td></tr><tr><td>1.93ビット</td><td>IQ1_M</td><td><strong>183GB</strong></td><td>公平</td><td><a href="https://huggingface.co/unsloth/DeepSeek-V3-0324-GGUF/tree/main/UD-IQ1_M">リンク</a></td><td>2.5/2.06/1.56</td></tr><tr><td>2.42ビット</td><td>IQ2_XXS</td><td><strong>203GB</strong></td><td><mark style="background-color:blue;"><strong>推奨</strong></mark></td><td><a href="https://huggingface.co/unsloth/DeepSeek-V3-0324-GGUF/tree/main/UD-IQ2_XXS">リンク</a></td><td>2.5/2.06ビット</td></tr><tr><td>2.71ビット</td><td>Q2_K_XL</td><td><strong>231GB</strong></td><td><mark style="background-color:purple;"><strong>推奨</strong></mark></td><td><a href="https://huggingface.co/unsloth/DeepSeek-V3-0324-GGUF/tree/main/UD-Q2_K_XL">リンク</a></td><td>3.5/2.5ビット</td></tr><tr><td>3.5ビット</td><td>Q3_K_XL</td><td><strong>320GB</strong></td><td>素晴らしい</td><td><a href="https://huggingface.co/unsloth/DeepSeek-V3-0324-GGUF/tree/main/UD-Q3_K_XL">リンク</a></td><td>4.5/3.5ビット</td></tr><tr><td>4.5ビット</td><td>Q2_K_XL（動的2ビット量子化）や</td><td><strong>406GB</strong></td><td>最高</td><td><a href="https://huggingface.co/unsloth/DeepSeek-V3-0324-GGUF/tree/main/UD-Q4_K_XL">リンク</a></td><td>5.5/4.5ビット</td></tr></tbody></table>

{% hint style="success" %}
DeepSeek V3の元のアップロードはfloat8で、715GBかかります。Q4\_K\_Mを使うとファイルサイズは約404GBに半減し、我々の動的1.78ビット量子化は約151GBに収まります。 **サイズと精度のバランスを取るために、我々の2.7ビット量子化を使うことを推奨します！2.4ビットのものもよく機能します！**
{% endhint %}

## :gear: 公式推奨設定

によると [DeepSeek](https://huggingface.co/deepseek-ai/DeepSeek-V3-0324)、これらが推論の推奨設定です：

* <mark style="background-color:blue;">**Temperature（温度）0.3**</mark> （コーディングではおそらく0.0、 [こちらで確認）](https://api-docs.deepseek.com/quick_start/parameter_settings))
* Min\_Pを0.00（オプション、但し0.01がよく機能します。llama.cppのデフォルトは0.1）
* チャットテンプレート： `<｜User｜>Pythonで簡単に遊べるFlappy Birdゲームを作成してください。完成したゲームはマークダウンのセクション内に配置してください。<｜Assistant｜>`
* BOSトークンは `<｜begin▁of▁sentence｜>` トークナイゼーション時に自動的に追加されます（手動で追加しないでください！）
* DeepSeekは <mark style="background-color:green;">**システムプロンプト**</mark> も使用すると述べています（オプション）—それは中国語です： `该助手为DeepSeek Chat，由深度求索公司创造。\n今天是3月24日，星期一。` は次のように翻訳されます： `このアシスタントはDeepSeek Chatで、DeepSeekによって作成されました。\n今日は3月24日、月曜日です。`
* <mark style="background-color:orange;">**KVキャッシュの量子化には8ビットを使用してください。4ビットでは明らかに性能が悪いことが分かっています。**</mark>

## 📖 チュートリアル：llama.cppでDeepSeek-V3を実行する方法

1. 最新の `llama.cpp` を [GitHubで入手してください](https://github.com/ggml-org/llama.cpp)。以下のビルド手順にも従うことができます。を変更してください `-DGGML_CUDA=ON` に `-DGGML_CUDA=OFF` GPUを持っていない場合やCPUで推論したい場合は **Apple Mac / Metalデバイスの場合**、次を設定してください `-DGGML_CUDA=OFF` その後通常通り続行してください — Metalサポートはデフォルトで有効です。

{% hint style="warning" %}
注： `-DGGML_CUDA=ON` をGPU向けに使用するとコンパイルに5分かかる場合があります。CPUのみでは1分でコンパイルできます。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. モデルをダウンロードするには（をインストールした後） `モデルをダウンロードするには（` を選択できます。 `UD-IQ1_S`（動的 1.78bit 量子化）や他の量子化バージョンのような `Q4_K_M` . <mark style="background-color:green;">**我々の2.7ビット動的量子化の使用を推奨します**</mark><mark style="background-color:green;">**&#x20;**</mark><mark style="background-color:green;">**`サイズと精度のバランスを取るために私たちの2.7ビット動的量子化を`**</mark><mark style="background-color:green;">**&#x20;**</mark><mark style="background-color:green;">**UD-Q2\_K\_XL**</mark>などがあります。さらに多くのバージョンは： <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*"], # 動的2.7ビット（230GB） 動的1.78ビット（151GB）には "*UD-IQ_S*" を使用
)
```

{% endcode %}

3. UnslothのFlappy Birdテストを、DeepSeek R1の1.58ビット動的量子化で説明したとおりに実行してください。
4. 編集 `次の` --threads 32 `はCPUスレッドの数、` --ctx-size 16384 `はコンテキスト長、` --n-gpu-layers 2

<pre class="language-bash" data-overflow="wrap"><code class="lang-bash">export LLAMA_CACHE="unsloth/GLM-4.7-GGUF"
    --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">はコンテキスト長、</a> \
    -no-cnv \
    --fit on \
    --temp 0.3 \
    --min-p 0.01 \
    <a data-footnote-ref href="#user-content-fn-4">--ctx-size 4096</a> \
    --model unsloth/GLM-4.7-GGUF/UD-Q2_K_XL/GLM-4.7-UD-Q2_K_XL-00001-of-00003.gguf \
    --prompt "&#x3C;｜User｜>PythonでFlappy Birdゲームを作成してください。以下の点を必ず含めてください:\n1. pygame を使用すること。\n2. 背景色はランダムに選択され、淡い色合いにすること。最初は薄い青色から始めること。\n3. SPACE を複数回押すと鳥が加速すること。\n4. 鳥の形状はランダムに四角形、円、三角形のいずれかにし、色はランダムに暗い色にすること。\n5. 画面下部に、ランダムに選ばれた暗い茶色または黄色の土地を配置すること。\n6. スコアを右上に表示すること。パイプを通過して当たらなかった場合に増加させること。\n7. 十分な間隔のランダムな間隔でパイプを配置すること。色はランダムに濃い緑、薄い茶色、または暗い灰色のいずれかにすること。\n8. ゲームオーバー時にベストスコアを表示すること。テキストは画面内に表示すること。q または Esc を押すとゲームを終了すること。再開は再び SPACE を押すこと。\n最終的なゲームは Python のマークダウンセクション内に入れること。コードのエラーを確認して最終マークダウンセクションの前に修正してください。&#x3C;｜Assistant｜>"
</code></pre>

<details>

<summary>上記を実行すると、非常に異なる2つの結果が得られます。<br><br><strong>標準の2ビット版：</strong> 結果を見るにはクリック <em><mark style="color:赤;"><strong>（発作注意！）</strong></mark></em><br><strong>動的2ビット版：</strong> 以下に結果を示します：</summary>

<img src="https://735611837-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">

標準の2ビット。背景で失敗、衝突でも失敗

</details>

<div align="center"><figure><img src="https://735611837-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>動的2ビット。プレイ可能なゲームの作成に成功。</p></figcaption></figure></div>

5. DeepSeek-R1と同様に、V3は61層あります。たとえば24GB GPUや80GB GPUでは、四捨五入してオフロードすると（メモリ不足になる場合は1層減らす）、次のようになります：

| 量子化     | ファイルサイズ | 24GB GPU | 80GB GPU | 2x80GB GPU |
| ------- | ------- | -------- | -------- | ---------- |
| 1.73bit | 173GB   | 5        | 25       | 56         |
| 2.22bit | 183GB   | 4        | 22       | 49         |
| 2.51bit | 212GB   | 2        | 19       | 32         |

### Mac / Apple デバイスでの実行

Apple Metalデバイスでは、次に注意してください： `--n-gpu-layers`。マシンがメモリ不足になる場合はこれを減らしてください。128GBの統一メモリマシンでは、およそ59層をオフロードできるはずです。

```bash
export LLAMA_CACHE="unsloth/GLM-4.7-GGUF"
    --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 \
    --model unsloth/GLM-4.7-GGUF/UD-Q2_K_XL/GLM-4.7-UD-Q2_K_XL-00001-of-00003.gguf \
    --n-gpu-layers 59 \
    -no-cnv \
    --prompt "<｜User｜>Create a Flappy Bird game in Python.<｜Assistant｜>"
```

## :8ball: ヘプタゴンテスト

我々はまた動的量子化を通じてテストします： [r/Localllama](https://www.reddit.com/r/LocalLLaMA/comments/1j7r47l/i_just_made_an_animation_of_a_ball_bouncing/) そこでモデルは、移動する閉じた七角形の中で回転するボールをシミュレートする基本的な物理エンジンを作成するテストを受けます。

<figure><img src="https://735611837-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>目標は七角形を回転させ、七角形内のボールが動くようにすることです。</p></figcaption></figure>

{% code overflow="wrap" %}

```bash
export LLAMA_CACHE="unsloth/GLM-4.7-GGUF"
    --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 \
    --fit on \
    --temp 0.3 \
    --min_p 0.01 \
    --ctx-size 4096 \
    --model unsloth/GLM-4.7-GGUF/UD-Q2_K_XL/GLM-4.7-UD-Q2_K_XL-00001-of-00003.gguf \
    --prompt "<｜User｜>回転する七角形の中で20個のボールが跳ねるPythonプログラムを書いてください:\n- すべてのボールは同じ半径を持ちます。\n- すべてのボールには1から20の番号が付いています。\n- 開始時にすべてのボールは七角形の中心から落ちます。\n- 色は次の通り：#f8b862, #f6ad49, #f39800, #f08300, #ec6d51, #ee7948, #ed6d3d, #ec6800, #ec6800, #ee7800, #eb6238, #ea5506, #ea5506, #eb6101, #e49e61, #e45e32, #e17b34, #dd7a56, #db8449, #d66a35\n- ボールは重力と摩擦の影響を受け、回転する壁に対して現実的に跳ね返らなければなりません。ボール同士の衝突も必要です。\n- すべてのボールの素材により、衝突後の跳ね上がり高さは七角形の半径を超えないが、ボール半径より大きくなります。\n- すべてのボールは摩擦で回転し、ボール上の番号はボールの回転を示すのに使用できます。\n- 七角形は中心を中心に回転し、回転速度は5秒で360度です。\n- 七角形のサイズはすべてのボールを収容できる十分な大きさにしてください。\n- pygameライブラリを使用しないでください。衝突検出アルゴリズムや衝突応答などは自分で実装してください。次のPythonライブラリが許可されています：tkinter, math, numpy, dataclasses, typing, sys。\n- すべてのコードは単一のPythonファイルにまとめてください。<｜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>非動的2ビット。失敗 - <mark style="background-color:red;">発作注意</mark> 再び！</td><td><a href="https://735611837-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://735611837-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>動的2ビット。実際にヘプタゴンパズルを正しく解きます！！</td><td><a href="https://735611837-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://735611837-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>元のfloat8</td><td><a href="https://735611837-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://735611837-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>

サイズがわずか230GBの動的2.7ビット量子化は実際にヘプタゴンパズルを解くことに成功しました！3つのバージョンすべて（完全なfp8を含む）の完全な出力は以下の通りです：

<details>

<summary>動的2ビット ヘプタゴンコード</summary>

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

# 定数
HEPTAGON_RADIUS = 300
BALL_RADIUS = 20
GRAVITY = 0.2
FRICTION = 0.99
BOUNCE_FACTOR = 0.8
ROTATION_SPEED = 360 / 5  # 秒あたりの度数
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):
        # 初期の七角形の壁を作成
        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
        
        # 経過時間を計算（概算）
        dt = 0.016  # 約60FPSと仮定
        
        # 七角形の回転を更新
        self.heptagon_angle += ROTATION_SPEED * dt
        self.update_heptagon_walls(self.heptagon_angle)
        
        # ボールを更新
        for ball in self.balls:
            # 重力を適用
            ball.vy += GRAVITY
            
            # 摩擦を適用
            ball.vx *= FRICTION
            ball.vy *= FRICTION
            ball.spin *= SPIN_FRICTION
            
            # ボールを移動
            ball.x += ball.vx
            ball.y += ball.vy
            
            # 壁との衝突をチェック
            self.check_wall_collisions(ball)
            
            # 他のボールとの衝突をチェック
            for other in self.balls:
                if other.number != ball.number:
                    self.check_ball_collision(ball, other)
        
        # すべてを描画
        self.draw()
    
    def check_wall_collisions(self, ball):
        for wall in self.walls:
            # 壁の線分上でボールに最も近い点を見つける
            closest = self.closest_point_on_segment(
                wall.x1, wall.y1, wall.x2, wall.y2, ball.x, ball.y
            )
            
            # 壁までの距離を計算
            dx = ball.x - closest[0]
            dy = ball.y - closest[1]
            distance = math.sqrt(dx*dx + dy*dy)
            
            if distance < BALL_RADIUS:
                # 衝突検出
                # 法線ベクトルを計算
                nx = dx / distance
                ny = dy / distance
                
                # 法線方向の相対速度を計算
                v_rel = ball.vx * nx + ball.vy * ny
                
                if v_rel < 0:  # 壁に向かって移動している
                    # インパルスを計算
                    j = -(1 + BOUNCE_FACTOR) * v_rel
                    
                    # インパルスを適用
                    ball.vx += j * nx
                    ball.vy += j * ny
                    
                    # 衝突に基づく回転を追加
                    ball.spin += (ball.vx * ny - ball.vy * nx) * 0.1
                    
                    # 衝突からボールを移動させる
                    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:
            # 衝突検出
            nx = dx / distance
            ny = dy / distance
            
            # 相対速度を計算
            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:  # 互いに近づいている
                # インパルスを計算
                j = -(1 + BOUNCE_FACTOR) * v_rel / 2
                
                # インパルスを適用
                ball1.vx -= j * nx
                ball1.vy -= j * ny
                ball2.vx += j * nx
                ball2.vy += j * ny
                
                # 衝突に基づく回転を追加
                ball1.spin += (ball1.vx * ny - ball1.vy * nx) * 0.05
                ball2.spin += (ball2.vx * ny - ball2.vy * nx) * 0.05
                
                # ボールを引き離す
                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):
        # 点から線分の開始点へのベクトル
        dx = x - x1
        dy = y - y1
        
        # 線分ベクトル
        sx = x2 - x1
        sy = y2 - y1
        
        # 点の線分への射影
        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
        out = MAP_FN[fx](**json.loads(args))
            return x1 + param * sx, y1 + param * sy
    
    def draw(self):
        self.canvas.delete("all")
        
        # 七角形を描画
        points = []
        for wall in self.walls:
            points.extend([wall.x1, wall.y1])
        self.canvas.create_polygon(points, fill="", outline="black", width=2)
        
        # ボールを描画
        for ball in self.balls:
            # ボールを描画
            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"
            )
            
            # 回転に基づいて番号を描画
            angle = ball.spin * 10  # 視覚効果のために回転を拡大
            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("回転する七角形の中の跳ねるボール")
    app = BouncingBalls(root)
    root.mainloop()
```

</details>

<details>

<summary>非動的2ビット ヘプタゴンコード</summary>

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

# 定数
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  # 5秒で360度
SPIN_DECAY = 0.99

# ボールの色
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")
        
        # 七角形の角度を更新
        self.heptagon.angle += ROTATION_SPEED / 60  # 60FPSを仮定
        
        # 七角形を描画
        self.draw_heptagon()
        
        # ボールを更新して描画
        for ball in self.balls:
            # 重力を適用
            ball.vy += GRAVITY
            
            # 位置を更新
            ball.x += ball.vx
            ball.y += ball.vy
            
            # 摩擦を適用
            ball.vx *= FRICTION
            ball.vy *= FRICTION
            
            # 回転減衰を適用
            ball.spin *= SPIN_DECAY
            
            # 七角形の壁との衝突をチェック
            self.check_heptagon_collision(ball)
            
            # 他のボールとの衝突をチェック
            for other in self.balls:
                if other != ball:
                    if self.check_ball_collision(ball, other):
                        self.resolve_ball_collision(ball, other)
            
            # ボールを描画
            self.draw_ball(ball)
        
        self.root.after(16, self.update)  # 約60FPS
    
    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))
        
        # 七角形を描画
        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"
        )
        
        # 番号を描く
        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
        
        # 中心からの距離をチェック
        dx = ball.x - center_x
        dy = ball.y - center_y
        dist = math.sqrt(dx**2 + dy**2)
        
        if dist + ball.radius > self.heptagon.radius:
            # 中心からボールへの法線ベクトルを求める
            angle = math.atan2(dy, dx)
            normal_x = math.cos(angle)
            normal_y = math.sin(angle)
            
            # ボールを七角形の内側に戻す
            overlap = (dist + ball.radius) - self.heptagon.radius
            ball.x -= overlap * normal_x
            ball.y -= overlap * normal_y
            
            # 速度を反射
            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)
        
        # 法線ベクトル
        nx = dx / distance
        ny = dy / distance
        
        # 相対速度
        dvx = ball2.vx - ball1.vx
        dvy = ball2.vy - ball1.vy
        
        # インパルスを計算
        impulse = 2 * (dvx * nx + dvy * ny) / 2
        impulse *= ELASTICITY
        
        # インパルスを適用
        ball1.vx -= impulse * nx
        ball1.vy -= impulse * ny
        ball2.vx += impulse * nx
        ball2.vy += impulse * ny
        
        # ボールがくっつくのを防ぐために分離
        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("回転する七角形の中の跳ねるボール")
    app = BouncingBalls(root)
    app.run()
```

</details>

<details>

<summary>Float8 ヘプタゴンコード</summary>

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

# 定数
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  # 秒あたりの度数
ELASTICITY = 0.8
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
    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:
            # 衝突法線を計算する
            nx = dx / distance
            ny = dy / distance
            
            # 相対速度を計算
            dvx = other.vx - self.vx
            dvy = other.vy - self.vy
            
            # インパルスを計算
            impulse = 2 * (dvx * nx + dvy * ny) / (1/self.radius + 1/other.radius)
            
            # インパルスを適用
            self.vx += impulse * nx / self.radius
            self.vy += impulse * ny / self.radius
            other.vx -= impulse * nx / other.radius
            other.vy -= impulse * ny / other.radius
            
            # ボールがくっつくのを防ぐために分離する
            overlap = (self.radius + other.radius - distance) / 2
            self.x -= overlap * nx
            self.y -= overlap * ny
            other.x += overlap * nx
            other.y += overlap * ny
            
            # 回転（スピン）を一部転送する
            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):
            # すべてのボールを中心に配置し、小さなランダムな速度で開始する
            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
        
        # 七角形の各辺との衝突をチェックする
        for i in range(len(vertices)):
            p1 = vertices[i]
            p2 = vertices[(i + 1) % len(vertices)]
            
            # p1からp2へのベクトル
            edge_x = p2[0] - p1[0]
            edge_y = p2[1] - p1[1]
            edge_length = math.hypot(edge_x, edge_y)
            
            # 辺ベクトルを正規化する
            edge_x /= edge_length
            edge_y /= edge_length
            
            # 法線ベクトル（辺に対して垂直で内側を向く）
            nx = -edge_y
            ny = edge_x
            
            # p1からボールへのベクトル
            ball_to_p1_x = ball.x - p1[0]
            ball_to_p1_y = ball.y - p1[1]
            
            # ボールを辺の法線に射影する
            projection = ball_to_p1_x * nx + ball_to_p1_y * ny
            
            # 射影が負の場合、ボールは七角形の外側にある
            if projection < ball.radius:
                # 辺上でボールに最も近い点を見つける
                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
                
                # ボールと辺上の最も近い点との距離
                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:
            # 反発の応答を計算する
            dot_product = ball.vx * closest_normal[0] + ball.vy * closest_normal[1]
            
            # 反発を弾性率を用いて適用する
            ball.vx -= (1 + ELASTICITY) * dot_product * closest_normal[0]
            ball.vy -= (1 + ELASTICITY) * dot_product * closest_normal[1]
            
            # 衝撃に基づいてスピンを追加する
            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)
                # 速度と辺方向の外積
                spin_effect = (ball.vx * edge_vec[1] - ball.vy * edge_vec[0]) * 0.1
                ball.spin += spin_effect
            
            # ボールがくっつくのを防ぐために七角形の外側へ移動させる
            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
        
        # キャンバスをクリアする
        self.canvas.delete('all')
        
        # 七角形の回転を更新
        self.heptagon_angle += ROTATION_SPEED / 60  # おおよそ60FPSを想定
        
        # 七角形を描画
        vertices = self.get_heptagon_vertices()
        self.canvas.create_polygon(vertices, outline='black', fill='', width=2)
        
        # ボールを更新して描画
        for i, ball in enumerate(self.balls):
            # ボールを移動
            ball.move()
            
            # 七角形との衝突をチェック
            self.check_ball_heptagon_collision(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'
            )
            
            # 回転に基づいて番号を描画
            angle = ball.spin * 10  # 目に見える回転のためにスピンを拡大
            self.canvas.create_text(
                ball.x, ball.y,
                text=str(ball.number),
                font=('Arial', 10, 'bold'),
                angle=angle
            )
        
        # ボール同士の衝突をチェック
        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])
        
        # 次の更新をスケジュールする
        self.last_time = self.root.after(16, self.update)  # 約60FPS

if __name__ == '__main__':
    root = tk.Tk()
    root.title('Bouncing Balls in a Spinning Heptagon')
    simulator = HeptagonBounceSimulator(root)
    root.mainloop()
```

</details>

## :detective: 追加の発見とヒント

1. 実験的テストでは、KVキャッシュの低ビット量化（4ビット）を使用すると生成品質が低下するように見えます — さらにテストが必要ですが、以下を使用することを推奨します。 `q8_0` キャッシュ量子化の目的は、KVキャッシュがかなりのメモリを使用するため、より長いコンテキスト長をサポートすることです。
2. 我々は `down_proj` このモデルでは量子化に極めて敏感であることを発見しました。2ビットを使用していた動的量子化の一部をやり直す必要があり、これらの行列に対しては現在最小で3ビットを使用しています。 `down_proj` and now we use 3bits as the minimum for all these matrices.
3. 使用すると、 `llama.cpp` のFlash Attentionバックエンドはデコード速度をやや向上させる結果になります。コンパイル時にを使用してください。 また、 `-DGGML_CUDA_FA_ALL_QUANTS=ON` <https://developer.nvidia.com/cuda-gpus> [で見つかるようにCUDAアーキテクチャを設定するのが最良です。これによりコンパイル時間を短縮し、その後以下で設定します。](https://developer.nvidia.com/cuda-gpus) -DCMAKE\_CUDA\_ARCHITECTURES="80" `使用する場合、`
4. min\_p=0.01 `おそらく十分です。`のデフォルトは0.1で、これはおそらく不要です。温度0.3が使用されているため、低確率トークンをサンプリングする可能性は非常に低く、非常にありそうもないトークンを除外するのは良い考えです。DeepSeekはコーディング作業に対して温度0.0を推奨します。 `llama.cpp`defaults to 0.1, which is probably not necessary. Since a temperature of 0.3 is used anyways, we most likely will very unlikely sample low probability tokens, so removing very unlikely tokens is a good idea. DeepSeek recommends 0.0 temperature for coding tasks.

[^1]: 必ず8ビットを使用してください—4ビットではありません

[^2]: マシンのCPUスレッド数

[^3]: 24GB GPUでは概ね2、80GB GPUでは概ね18。

[^4]: コンテキスト長


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://unsloth.ai/docs/jp/moderu/tutorials/deepseek-v3-0324-how-to-run-locally.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
