> 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/jp/moderu/tutorials/deepseek-v3-0324-how-to-run-locally.md).

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

精度を回復するDynamic量子化を使って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.78bit</td><td>IQ1_S</td><td><strong>173GB</strong></td><td>了解</td><td><a href="https://huggingface.co/unsloth/DeepSeek-V3-0324-GGUF/tree/main/UD-IQ1_S">リンク</a></td><td>2.06/1.56bit</td></tr><tr><td>1.93bit</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.42bit</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.06bit</td></tr><tr><td>2.71bit</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.5bit</td></tr><tr><td>3.5bit</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.5bit</td></tr><tr><td>4.5bit</td><td>Q4_K_XL</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.5bit</td></tr></tbody></table>

{% hint style="success" %}
DeepSeek V3の元のアップロードはfloat8で、715GBあります。Q4\_K\_Mを使うとファイルサイズは約404GBに半減し、私たちの動的1.78bit量子化なら約151GBに収まります。 **サイズと精度のバランスを取るために、私たちの2.7bit量子化を使うことをおすすめします！ 2.4bit版もうまく動きます！**
{% endhint %}

## :gear: 公式推奨設定

によると [DeepSeek](https://huggingface.co/deepseek-ai/DeepSeek-V3-0324)、推論の推奨設定は以下のとおりです：

* <mark style="background-color:blue;">**温度 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で、回転する七角形の中で20個のボールが跳ねる、シンプルに遊べるゲームを作成してください。`\
  `- すべてのボールは同じ半径にしてください。`\
  `- すべてのボールには1から20までの番号を付けてください。`\
  `- すべてのボールは開始時に七角形の中心から落下します。`\
  `- 色は次のとおりです: #f8b862, #f6ad49, #f39800, #f08300, #ec6d51, #ee7948, #ed6d3d, #ec6800, #ec6800, #ee7800, #eb6238, #ea5506, #ea5506, #eb6101, #e49e61, #e45e32, #e17b34, #dd7a56, #db8449, #d66a35`\
  `- ボールは重力と摩擦の影響を受け、回転する壁で現実的に跳ね返らなければなりません。ボール同士の衝突も必要です。`\
  `- すべてのボールの材質により、衝突時の跳ね返りの高さは七角形の半径を超えないが、ボールの半径よりは高くなるようにしてください。`\
  `- すべてのボールは摩擦で回転し、ボールの数字でボールのスピンを示せます。`\
  `- 七角形は中心の周りを回転しており、回転速度は5秒で360度です。`\
  `- 七角形の大きさは、すべてのボールを収められるのに十分な大きさにしてください。`\
  `- pygameライブラリは使用せず、衝突検出アルゴリズムや衝突応答などを自分で実装してください。以下のPythonライブラリは使用可能です: tkinter, math, numpy, dataclasses, typing, sys。`\
  `- すべてのコードは1つのPythonファイルにまとめてください。<｜Assistant｜>`
* BOSトークン `<｜begin▁of▁sentence｜>` はトークン化の際に自動で追加されます（手動で追加しないでください！）
* DeepSeekは次のような <mark style="background-color:green;">**システムプロンプト**</mark> も使用していると述べました（任意） - 中国語です： `このアシスタントはDeepSeek Chatであり、深度求索社によって作成されました。\n今日は3月24日、月曜日です。` これは次のように翻訳されます： `このアシスタントはDeepSeekによって作成されたDeepSeek Chatです。\n今日は3月24日、月曜日です。`
* <mark style="background-color:orange;">**KVキャッシュの量子化には、4bitではなく8bitを使用してください。明らかに性能が悪いことが分かりました。**</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. 以下をインストールした後、( `pip install huggingface_hub hf_transfer` をインストール後）。 `UD-IQ1_S`（動的 1.78bit 量子化）または次のような他の量子化版 `Q4_K_M` . <mark style="background-color:green;">**私たちの2.7bit動的量子化の使用をおすすめします**</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;">**サイズと精度のバランスを取るために**</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.7bit (230GB) 1.78bit動的版 (151GB) には "*UD-IQ_S*" を使用
)
```

{% endcode %}

3. DeepSeek R1向けの1.58bit動的量子化で説明したとおりに、UnslothのFlappy Birdテストを実行してください。
4. 編集 `--threads 32` CPUスレッド数は `--ctx-size 16384` コンテキスト長は `--n-gpu-layers 2` GPUオフロードする層数です。GPUがメモリ不足になったら調整してみてください。CPUのみで推論する場合は削除してください。

<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｜>Python で Flappy Bird ゲームを作ってください。次の内容を含める必要があります:\n1. pygame を使用する必要があります。\n2. 背景色はランダムに選ばれる明るい色にしてください。最初は薄い青色にします。\n3. SPACE を何度も押すと鳥が加速します。\n4. 鳥の形は四角、円、三角形のいずれかをランダムに選びます。色はランダムに暗い色を選びます。\n5. 画面下部に、ランダムに選ばれた濃い茶色または黄色の地面を配置します。\n6. スコアを右上に表示します。パイプを通過してぶつからなければ加算してください。\n7. 十分な間隔を空けて、ランダムな間隔でパイプを配置します。色はランダムに濃い緑、薄い茶色、または暗いグレー系の色にします。\n8. 負けたら最高スコアを表示します。文字は画面内に表示してください。q または Esc を押すとゲームを終了します。再開はもう一度 SPACE を押します。\n最終的なゲームは Python の markdown セクション内に入れてください。最終的な markdown セクションの前にコードのエラーを確認し、修正してください。&#x3C;｜Assistant｜>"
</code></pre>

<details>

<summary>上記を実行すると、まったく異なる2つの結果が得られます。<br><br><strong>標準の2-bit版:</strong> クリックして結果を表示 <em><mark style="color:赤;"><strong>（発作警告！）</strong></mark></em><br><strong>動的2-bit版:</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-bit。背景で失敗、衝突で失敗

</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-bit。プレイ可能なゲームの作成に成功。</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
./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｜>Python で Flappy Bird ゲームを作ってください。<｜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
./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｜>回転する七角形の中で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- すべてのコードは1つの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>非動的2bit。失敗 - <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>動的2bit。実際に七角形パズルを正しく解きます！！</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.7bit量子化が、実際に七角形パズルの解決に成功しました！ 3つのバージョンすべて（完全なfp8を含む）の完全な出力は以下です：

<details>

<summary>動的2bit 七角形コード</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  # 1秒あたりの回転角度
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
        else:
            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>非動的2bit 七角形コード</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  # 60 FPSを想定
        
        # 七角形を描画
        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)  # 約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))
        
        # 七角形を描画
        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  # 1秒あたりの回転角度
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  # 約60 FPSを想定
        
        # 七角形を描画
        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)  # 約60 FPS

if __name__ == '__main__':
    root = tk.Tk()
    root.title('回転するヘプタゴンの中で跳ねるボール')
    simulator = HeptagonBounceSimulator(root)
    root.mainloop()
```

</details>

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

1. 経験的なテストでは、低いKVキャッシュ量子化（4bit）を使うと生成品質が低下するようです。さらにテストが必要ですが、使用を推奨します `q8_0` キャッシュの量子化。量子化の目的は、KVキャッシュがかなりのメモリを使うため、より長いコンテキスト長をサポートすることです。
2. 私たちはその `down_proj` このモデルでは量子化に非常に敏感であることが分かりました。2ビットを使っていた一部の動的量子化をやり直す必要がありました。 `down_proj` そして今では、これらの行列すべてに対して最小値として3ビットを使っています。
3. 使用すると `llama.cpp` のFlash Attentionバックエンドは、デコード速度をある程度向上させます。 `-DGGML_CUDA_FA_ALL_QUANTS=ON` コンパイル時に使用してください。 <https://developer.nvidia.com/cuda-gpus> コンパイル時間を短縮するために、こちらで見つかるCUDAアーキテクチャを設定し、 `-DCMAKE_CUDA_ARCHITECTURES="80"`
4. a `min_p=0.01`で十分でしょう。 `llama.cpp`は0.1がデフォルトですが、おそらく必要ありません。いずれにせよ温度0.3が使われるため、確率の低いトークンはほとんどサンプルされないはずです。そのため、極めて起こりにくいトークンを取り除くのは良い考えです。DeepSeekはコーディングタスクに対して温度0.0を推奨しています。

[^1]: 必ず8bitを使用 - 4bitではありません

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

[^3]: 24GB GPUでは約2。80GB GPUでは約18。

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


---

# 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/jp/moderu/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.
