> 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/glm-4.7-flash.md).

# GLM-4.7-Flash: ローカルでの実行方法

GLM-4.7-Flash は Z.ai の新しい 30B MoE 推論モデルで、ローカルデプロイ向けに構築されています。コーディング、エージェント的ワークフロー、チャットでクラス最高の性能を発揮します。約 36 億パラメータを使用し、200K コンテキストをサポートし、SWE-Bench、GPQA、推論/チャットのベンチマークで首位です。

GLM-4.7-Flash は次で動作します **24GB RAM**/VRAM/統合メモリ（フル精度では 32GB）が必要で、現在は Unsloth でファインチューニングできます。vLLM で GLM 4.7 Flash を実行するには、こちらを参照してください [#glm-4.7-flash-in-vllm](#glm-4.7-flash-in-vllm "mention")

{% hint style="success" %}
1月21日更新: `llama.cpp` 誤った `scoring_func`: `"softmax"` （本来は `"sigmoid"`であるべき）。これがループと質の悪い出力の原因でした。GGUF を更新したので、より良い出力のためにモデルを再ダウンロードしてください。

現在は、Z.ai 推奨のパラメータを使って、素晴らしい結果を得られます:

* **一般用途:** `--temp 1.0 --top-p 0.95`
* **ツール呼び出し用:** `--temp 0.7 --top-p 1.0`
* **繰り返しペナルティ:** 無効にするか、次を設定してください `--repeat-penalty 1.0`

1月22日: CUDA 向けの FA 修正がマージされたため、より高速な推論が利用可能になりました。
{% endhint %}

<a href="/pages/68cc5d489fe86eefb1bb9cd2e351bcdb90866b49#run-glm-4.7-flash" class="button primary">実行チュートリアル</a><a href="/pages/68cc5d489fe86eefb1bb9cd2e351bcdb90866b49#fine-tuning-glm-4.7-flash" class="button secondary">ファインチューニング</a>

実行する GLM-4.7-Flash GGUF: [unsloth/GLM-4.7-Flash-GGUF](https://huggingface.co/unsloth/GLM-4.7-Flash-GGUF)

### ⚙️ 使用ガイド

最良の性能を得るには、利用可能な総メモリ（VRAM + システムRAM）が、ダウンロードする量子化モデルファイルのサイズを上回っていることを確認してください。そうでない場合でも、llama.cppはSSD/HDDオフロード経由で実行できますが、推論は遅くなります。

Z.ai のチームと話した結果、彼らは GLM-4.7 のサンプリングパラメータを使うことを推奨しています:

| デフォルト設定（ほとんどのタスク）                                                  | Terminal Bench、SWE Bench 検証済み                                      |
| ------------------------------------------------------------------ | ------------------------------------------------------------------ |
| <mark style="background-color:green;">**temperature = 1.0**</mark> | <mark style="background-color:green;">**temperature = 0.7**</mark> |
| <mark style="background-color:green;">**top\_p = 0.95**</mark>     | <mark style="background-color:green;">**top\_p = 1.0**</mark>      |
| 繰り返しペナルティ = 無効、または 1.0                                             | 繰り返しペナルティ = 無効、または 1.0                                             |

* 一般用途:  `--temp 1.0 --top-p 0.95`
* ツール呼び出し用:  `--temp 0.7 --top-p 1.0`
* llama.cpp を使う場合は、次を設定してください `--min-p 0.01` llama.cpp のデフォルトは 0.05 だからです
* ユースケースによって、どの数値が最適かは試してみる必要がある場合があります。

{% hint style="warning" %}
現時点では、 **推奨しません** この GGUF を **Ollama** 実行することは、チャットテンプレートの互換性に関する潜在的な問題があるためです。GGUF は llama.cpp（または LM Studio、Jan などのバックエンド）でうまく動作します。

**繰り返しペナルティを無効にするのを忘れずに！ または次を設定してください** `--repeat-penalty 1.0`
{% endhint %}

* **最大コンテキストウィンドウ：** `202,752`

### 🖥️ GLM-4.7-Flash を実行

用途によっては、異なる設定を使う必要があります。いくつかの GGUF は、モデルアーキテクチャ（たとえば [gpt-oss](/docs/jp/moderu/gpt-oss-how-to-run-and-fine-tune.md)）は 128 で割り切れない次元を持っているため、一部はより低いビットに量子化できないからです。

このガイドでは 4-bit を使うため、約 18GB の RAM/統合メモリが必要です。最高の性能を得るには、少なくとも 4-bit 精度を使うことを推奨します。

{% hint style="warning" %}
現時点では、 **推奨しません** この GGUF を **Ollama** 実行することは、チャットテンプレートの互換性に関する潜在的な問題があるためです。GGUF は llama.cpp（または LM Studio、Jan などのバックエンド）でうまく動作します。

**繰り返しペナルティを無効にするのを忘れずに！ または次を設定してください** `--repeat-penalty 1.0`
{% endhint %}

#### 🦥 Unsloth Studioガイド

GLM-4.7-Flash は [Unsloth Studio](/docs/jp/shii/studio.md)で実行およびファインチューニングできます。これはローカルAI向けの新しいオープンソースのWeb UIです。Unsloth Studio を使えば、モデルをローカルで **MacOS、Windows**、Linux、および次の機能：

{% columns %}
{% column %}

* 検索、ダウンロード、 [GGUFの実行](/docs/jp/shii/studio.md#run-models-locally) およびsafetensorモデル
* [**自己修復** ツール呼び出し](/docs/jp/shii/studio.md#execute-code--heal-tool-calling) + **ウェブ検索**
* [**コード実行**](/docs/jp/shii/studio.md#run-models-locally) （Python、Bash）
* [自動推論](https://unsloth.ai/docs/desktop#feature-deep-dive) パラメータ調整（temp、top-pなど）
* llama.cpp経由の高速CPU＋GPU推論
* [LLMの学習](/docs/jp/shii/studio.md#no-code-training) VRAMを70%削減しつつ2倍高速
  {% endcolumn %}

{% column %}

<div data-with-frame="true"><figure><img src="/files/c32867f999db074387ac16732ce548485cc593de" alt=""><figcaption></figcaption></figure></div>
{% endcolumn %}
{% endcolumns %}

{% stepper %}
{% step %}
**Unslothをインストール**

ターミナルで実行：

MacOS、Linux、WSL：

```bash
curl -fsSL https://unsloth.ai/install.sh | sh
```

Windows PowerShell：

```bash
irm https://unsloth.ai/install.ps1 | iex
```

{% hint style="success" %}
**インストールはすぐ完了し、約1～2分かかります。**
{% endhint %}
{% endstep %}

{% step %}
**Unslothを起動**

MacOS、Linux、WSL、およびWindows：

```bash
unsloth studio -H 0.0.0.0 -p 8888
```

次に開く `http://localhost:8888` をブラウザーで。
{% endstep %}

{% step %}
**GLM-4.7-Flash を検索してダウンロード**

初回起動時には、アカウントを保護し、後で再度サインインするためのパスワードを作成する必要があります。その後、モデル、データセット、基本設定を選ぶための簡単な初期設定ウィザードが表示されます。いつでもスキップできます。

次に〜へ移動し [Unsloth Chat](/docs/jp/shii/studio/chat.md) タブを開いて **GLM-4.7-Flash** を検索バーに入力し、目的のモデルと量子化版をダウンロードしてください。

<div data-with-frame="true"><figure><img src="/files/ca24c876304cbf8074c1511a37a6997169841fd3" alt="" width="375"><figcaption></figcaption></figure></div>
{% endstep %}

{% step %}
**GLM-4.7-Flash を実行**

Unsloth Studioを使うと推論パラメータは自動設定されますが、手動でも変更できます。コンテキスト長、チャットテンプレート、その他の設定も編集できます。

詳細については、次を参照してください [Unsloth Studio推論ガイド](/docs/jp/shii/studio/chat.md).

<div data-with-frame="true"><figure><img src="/files/44d9105dd956eac31f9586bcf01055a289b0ef3e" alt="" width="563"><figcaption></figcaption></figure></div>
{% endstep %}
{% endstepper %}

#### Llama.cpp チュートリアル（GGUF）:

llama.cpp で実行する手順（ほとんどのデバイスに収まるよう4ビットを使用します）：

{% stepper %}
{% step %}
最新の `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 サポートはデフォルトで有効です。

{% code overflow="wrap" %}

```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
cmake --build llama.cpp/build --config Release -j --clean-first --target llama-cli llama-mtmd-cli llama-server llama-gguf-split
cp llama.cpp/build/bin/llama-* llama.cpp
```

{% endcode %}
{% endstep %}

{% step %}
Hugging Face から直接取得できます。RAM/VRAM の許す限り、コンテキストを 200K まで増やせます。

Z.ai 推奨の GLM-4.7 サンプリングパラメータも試せます:

* 一般用途:  `--temp 1.0 --top-p 0.95`
* ツール呼び出し用:  `--temp 0.7 --top-p 1.0`
* **繰り返しペナルティを無効にするのを忘れずに！**

これに従ってください： **一般的な指示** ユースケース：

```bash
./llama.cpp/llama-cli \
    -hf unsloth/GLM-4.7-Flash-GGUF:UD-Q4_K_XL \\
    --ctx-size 16384 \\
    --temp 1.0 --top-p 0.95 --min-p 0.01
```

これに従ってください： **ツール呼び出し** ユースケース：

```bash
./llama.cpp/llama-cli \
    -hf unsloth/GLM-4.7-Flash-GGUF:UD-Q4_K_XL \\
    --ctx-size 16384 \\
    --temp 0.7 --top-p 1.0 --min-p 0.01
```

{% endstep %}

{% step %}
（以下をインストールした後）モデルを次の方法でダウンロードしてください `pip install huggingface_hub`をインストールした後）。 `UD-Q4_K_XL` または他の量子化版。ダウンロードが止まる場合は、こちらを参照してください [Hugging Face Hub、XETデバッグ](/docs/jp/ji-ben/troubleshooting-and-faqs/hugging-face-hub-xet-debugging.md)

{% code overflow="wrap" %}

```bash
pip install -U huggingface_hub
hf download unsloth/GLM-4.7-Flash-GGUF \\
    --local-dir unsloth/GLM-4.7-Flash-GGUF \\
    --include "*UD-Q2_K_XL*"
```

{% endcode %}
{% endstep %}

{% step %}
それでは、会話モードでモデルを実行します:

{% code overflow="wrap" %}

```bash
./llama.cpp/llama-cli \
    --model unsloth/GLM-4.7-Flash-GGUF/GLM-4.7-Flash-UD-Q4_K_XL.gguf \\
    --ctx-size 16384 \\
    --seed 3407 \
    --temp 1.0 \\
    --top-p 0.95 \\
    --min-p 0.01
```

{% endcode %}

また、 **コンテキストウィンドウ** 必要に応じて、最大で `202752`
{% endstep %}
{% endstepper %}

### :loop:繰り返しとループを軽減

{% hint style="success" %}
**1月21日更新: llama.cpp は、誤った** `"scoring_func": "softmax"` **を指定していたバグを修正しました。これがループと質の悪い出力の原因でした（本来は sigmoid であるべきです）。GGUF を更新しました。より良い出力のためにモデルを再ダウンロードしてください。**
{% endhint %}

つまり、Z.ai 推奨のパラメータを使って、素晴らしい結果を得られるようになったということです:

* 一般用途:  `--temp 1.0 --top-p 0.95`
* ツール呼び出し用:  `--temp 0.7 --top-p 1.0`
* llama.cpp を使う場合は、次を設定してください `--min-p 0.01` llama.cpp のデフォルトは 0.05 だからです
* **繰り返しペナルティを無効にするのを忘れずに！ または次を設定してください** `--repeat-penalty 1.0`

追加しました `"scoring_func": "sigmoid"` を `config.json` メインモデル用 - [参照](https://huggingface.co/unsloth/GLM-4.7-Flash/commit/3fd53b491e04f707f307aef2f70f8a7520511e6d).

{% hint style="warning" %}
現時点では、 **推奨しません** この GGUF を **Ollama** 実行することは、チャットテンプレートの互換性に関する潜在的な問題があるためです。GGUF は llama.cpp（または LM Studio、Jan などのバックエンド）でうまく動作します。
{% endhint %}

### :bird:UD-Q4\_K\_XL を使った Flappy Bird の例

例として、UD-Q4\_K\_XL を使って次の長い会話を行いました via `./llama.cpp/llama-cli --model unsloth/GLM-4.7-Flash-GGUF/GLM-4.7-Flash-UD-Q4_K_XL.gguf --fit on --temp 1.0 --top-p 0.95 --min-p 0.01` :

```
こんにちは
2+2 はいくつですか
Python で Flappy Bird ゲームを作成してください
Rust でまったく別のゲームを作成してください
両方のバグを見つけてください
最初に挙げたゲームを、単独の HTML ファイルで作成してください
バグを見つけて、修正版のゲームを見せてください
```

すると、次の Flappy Bird ゲームが HTML 形式でレンダリングされました:

<details>

<summary>HTML の Flappy Bird ゲーム（展開可能）</summary>

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Flappy Bird 修正版</title>
    <style>
        body {
            margin: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #222;
            font-family: 'Arial', sans-serif;
            overflow: hidden;
            user-select: none;
            -webkit-user-select: none;
            touch-action: none; /* モバイルでのズームを防止 */
        }

        #game-container {
            position: relative;
            box-shadow: 0 0 20px rgba(0,0,0,0.5);
        }

        canvas {
            background-color: #87CEEB;
            display: block;
            border-radius: 4px;
        }

        /* UI オーバーレイ */
        #ui-layer {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            pointer-events: none;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            text-align: center;
        }

        #score-display {
            position: absolute;
            top: 40px;
            left: 50%;
            transform: translateX(-50%);
            font-size: 48px;
            font-weight: bold;
            color: white;
            text-shadow: 3px 3px 0 #000;
            z-index: 10;
            font-family: 'Courier New', Courier, monospace;
        }

        #start-screen, #game-over-screen {
            background: rgba(0, 0, 0, 0.7);
            width: 100%;
            height: 100%;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            color: white;
            pointer-events: auto; /* クリックを許可 */
            cursor: pointer;
        }

        h1 { margin: 0 0 10px 0; font-size: 60px; text-shadow: 4px 4px 0 #000; line-height: 1; }
        p { font-size: 22px; margin: 10px 0; color: #ddd; }
        
        .btn {
            background: linear-gradient(to bottom, #ffeb3b, #fbc02d);
            border: 3px solid #fff;
            color: #333;
            padding: 15px 40px;
            font-size: 28px;
            font-weight: bold;
            cursor: pointer;
            border-radius: 8px;
            box-shadow: 0 6px 0 #c49000, 0 10px 10px rgba(0,0,0,0.3);
            text-transform: uppercase;
            transition: all 0.1s;
            margin-top: 10px;
        }

        .btn:active {
            transform: translateY(4px);
            box-shadow: 0 2px 0 #c49000, 0 4px 4px rgba(0,0,0,0.3);
        }

        .score-board {
            background: #ded895;
            border: 2px solid #543847;
            padding: 20px 40px;
            border-radius: 10px;
            box-shadow: 4px 4px 0 #543847;
            margin-bottom: 30px;
            display: none;
            border: 4px solid #543847;
        }
        
        .score-board h2 { margin: 0 0 5px 0; color: #e86101; font-size: 40px; }
        .score-board span { font-size: 20px; color: #543847; display: block; text-align: center; }

    </style>
</head>
<body>

    <div id="game-container">
        <canvas id="gameCanvas" width="400" height="600"></canvas>
        
        <div id="score-display">0</div>

        <div id="ui-layer">
            <div id="start-screen">
                <h1>FLAPPY<br>BIRD</h1>
                <p>タップするかスペースキーで開始</p>
                <button class="btn" style="display:none;" id="touch-instruction">クリックして開始</button>
            </div>

            <div id="game-over-screen">
                <h1>ゲームオーバー</h1>
                <div class="score-board" id="score-board">
                    <h2>スコア: <span id="final-score">0</span></h2>
                </div>
                <button class="btn" id="restart-btn">もう一度試す</button>
            </div>
        </div>
    </div>

<script>
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');

    // --- 定数 ---
    const GRAVITY = 0.35; // 体感を少し重くするための重力
    const JUMP_STRENGTH = -6.5;
    const PIPE_GAP = 180;
    const PIPE_WIDTH = 60;
    const PIPE_SPEED = 2.5;
    const PIPE_SPAWN_RATE = 100;

    // --- 状態 ---
    let frames = 0;
    let score = 0;
    let isGameOver = false;
    let isPlaying = false;
    let gameLoopId;

    const ui = {
        startScreen: document.getElementById('start-screen'),
        gameOverScreen: document.getElementById('game-over-screen'),
        scoreDisplay: document.getElementById('score-display'),
        scoreBoard: document.getElementById('score-board'),
        finalScore: document.getElementById('final-score'),
        restartBtn: document.getElementById('restart-btn')
    };

    const bird = {
        x: 80,
        y: 150,
        radius: 12, // 半径を固定
        velocity: 0,
        
        draw: function() {
            // 見た目の演出として速度に応じて鳥を回転
            let angle = Math.min(Math.PI / 4, Math.max(-Math.PI / 4, (this.velocity * 0.1)));
            
            ctx.save();
            ctx.translate(this.x, this.y);
            ctx.rotate(angle);
            
            // 本体を描画
            ctx.fillStyle = '#FFD700';
            ctx.beginPath();
            ctx.arc(0, 0, this.radius, 0, Math.PI * 2);
            ctx.fill();
            
            // 目
            ctx.fillStyle = 'white';
            ctx.beginPath();
            ctx.arc(4, -4, 4, 0, Math.PI * 2);
            ctx.fill();
            ctx.fillStyle = 'black';
            ctx.beginPath();
            ctx.arc(6, -4, 2, 0, Math.PI * 2);
            ctx.fill();
            
            // 羽
            ctx.fillStyle = '#FFA500';
            ctx.beginPath();
            ctx.arc(-4, 4, 5, 0, Math.PI * 2);
            ctx.fill();

            ctx.restore();
        },

        update: function() {
            this.velocity += GRAVITY;
            this.y += this.velocity;
        },

        jump: function() {
            this.velocity = JUMP_STRENGTH;
        },

        reset: function() {
            this.y = 150;
            this.velocity = 0;
        }
    };

    let pipes = [];

    function createPipe() {
        const minHeight = 50;
        const maxPos = canvas.height - PIPE_GAP - minHeight;
        const topHeight = Math.floor(Math.random() * (maxPos - minHeight + 1)) + minHeight;
        
        pipes.push({
            x: canvas.width,
            topHeight: topHeight,
            bottomY: topHeight + PIPE_GAP,
            width: PIPE_WIDTH,
            passed: false
        });
    }

    function drawPipes() {
        ctx.fillStyle = '#2ecc71';
        ctx.strokeStyle = '#27ae60';
        ctx.lineWidth = 2;
        
        pipes.forEach(pipe => {
            // 上のパイプ
            ctx.fillRect(pipe.x, 0, pipe.width, pipe.topHeight);
            ctx.strokeRect(pipe.x, 0, pipe.width, pipe.topHeight);
            
            // 下のパイプ
            ctx.fillRect(pipe.x, pipe.bottomY, pipe.width, canvas.height - pipe.bottomY);
            ctx.strokeRect(pipe.x, pipe.bottomY, pipe.width, canvas.height - pipe.bottomY);

            // キャップ
            const capH = 20;
            ctx.fillStyle = '#27ae60'; 
            ctx.fillRect(pipe.x - 2, pipe.topHeight - capH, pipe.width + 4, capH);
            ctx.fillRect(pipe.x - 2, pipe.bottomY, pipe.width + 4, capH);
        });
    }

    function updatePipes() {
        if (frames % PIPE_SPAWN_RATE === 0) createPipe();

        for (let i = 0; i < pipes.length; i++) {
            let p = pipes[i];
            p.x -= PIPE_SPEED;

            // --- 修正済みの衝突判定 ---
            // 鳥を半径 'bird.radius' の円として扱う
            // パイプは長方形: x, x+w, y_top, y_bottom
            let birdLeft = bird.x - bird.radius;
            let birdRight = bird.x + bird.radius;
            let birdTop = bird.y - bird.radius;
            let birdBottom = bird.y + bird.radius;

            // 水平方向の重なり
            if (birdRight > p.x && birdLeft < p.x + p.width) {
                // 垂直方向の重なり（上のパイプまたは下のパイプに当たった）
                if (birdTop < p.topHeight || birdBottom > p.bottomY) {
                    gameOver();
                }
            }

            // --- 修正済みのスコア判定 ---
            // パイプが左側で画面外に出ていて、まだ得点されていない場合
            if (p.x + p.width < 0 && !p.passed) {
                score++;
                p.passed = true;
                ui.scoreDisplay.innerText = score;
            }

            if (p.x < -60) {
                pipes.shift();
                i--;
            }
        }
    }

    function checkCollisions() {
        // 床
        if (bird.y + bird.radius >= canvas.height) {
            gameOver();
        }
        // 天井
        if (bird.y - bird.radius <= 0) {
            bird.y = bird.radius;
            bird.velocity = 0;
        }
    }

    function drawBackground() {
        // クリア
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        
        // 床
        ctx.fillStyle = '#654321';
        ctx.fillRect(0, canvas.height - 10, canvas.width, 10);
        
        // 雲
        ctx.fillStyle = "rgba(255, 255, 255, 0.6)";
        for(let i=0; i<4; i++) {
            let x = (frames * 0.5 + i * 150) % (canvas.width + 100) - 50;
            let y = (i * 40) + 20;
            let scale = 1 + (Math.sin(frames * 0.02 + i) * 0.1);
            let size = 30 * scale;
            ctx.beginPath();
            ctx.arc(x, y, size, 0, Math.PI * 2);
            ctx.arc(x + 20*scale, y - 10*scale, size * 1.2, 0, Math.PI * 2);
            ctx.arc(x + 40*scale, y, size, 0, Math.PI * 2);
            ctx.fill();
        }
    }

    function update() {
        if (!isPlaying) return;
        bird.update();
        updatePipes();
        checkCollisions();
        frames++;
    }

    function draw() {
        drawBackground();
        drawPipes();
        bird.draw();
    }

    function loop() {
        update();
        draw();
        if (isPlaying || !isGameOver) {
            gameLoopId = requestAnimationFrame(loop);
        }
    }

    function startGame() {
        isPlaying = true;
        isGameOver = false;
        
        // UI
        ui.startScreen.style.display = 'none';
        ui.gameOverScreen.style.display = 'none';
        ui.scoreBoard.style.display = 'none';
        
        // ロジック
        bird.reset();
        pipes = [];
        score = 0;
        frames = 0;
        ui.scoreDisplay.innerText = '0';
        
        loop();
    }

    function gameOver() {
        isPlaying = false;
        isGameOver = true;
        cancelAnimationFrame(gameLoopId);
        
        ui.finalScore.innerText = score;
        ui.gameOverScreen.style.display = 'flex';
        ui.scoreBoard.style.display = 'block';
    }

    // --- 入力処理 ---

    function handleInput(e) {
        if (e.type === 'keydown' && e.code === 'Space') e.preventDefault();

        if (isPlaying) {
            bird.jump();
        } else if (!isGameOver) {
            // スタート画面をクリック（またはゲーム未開始ならどこをクリックしても）
            startGame();
        }
    }

    // キーボード
    window.addEventListener('keydown', (e) => {
        if (e.code === 'Space') handleInput(e);
    });

    // マウス / タッチ
    window.addEventListener('mousedown', handleInput);
    window.addEventListener('touchstart', (e) => {
        // ズーム/スクロールを防止
        // e.preventDefault(); 
        handleInput(e);
    }, {passive: false});

    // UI の操作
    ui.restartBtn.addEventListener('click', (e) => {
        e.stopPropagation();
        startGame();
    });
    
    // ゲームオーバーのオーバーレイをクリックして再開できるようにする
    ui.gameOverScreen.addEventListener('mousedown', (e) => {
        if(e.target === ui.gameOverScreen) startGame();
    });
    ui.gameOverScreen.addEventListener('touchstart', (e) => {
        if(e.target === ui.gameOverScreen) {
            e.preventDefault();
            startGame();
        }
    });

    // 初期描画
    drawBackground();
    bird.reset();
    bird.draw();

</script>
</body>
</html>
```

</details>

そして、いくつかスクリーンショットを撮りました（4bit は動作します）:

<div align="left"><figure><img src="/files/cc6698126ce26defd572a77475906eb11168e8b7" alt="" width="188"><figcaption></figcaption></figure> <figure><img src="/files/d37d9be118ce0cfa73e55a8432762acc1b437be0" alt="" width="188"><figcaption></figcaption></figure></div>

### 🦥 GLM-4.7-Flash のファインチューニング

現在 Unsloth は GLM-4.7-Flash のファインチューニングをサポートしていますが、次を使う必要があります `transformers v5`. 30B モデルは無料の Colab GPU には収まりませんが、私たちのノートブックを使えます。GLM-4.7-Flash の 16-bit LoRA ファインチューニングではおよそ **60GB の VRAM**:

* [GLM-4.7-Flash SFT LoRA ノートブック](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/GLM_Flash_A100\(80GB\).ipynb)

{% hint style="warning" %}
A100 40GB VRAM を使うと、時々メモリ不足になることがあります。より安定して実行するには H100/A100 80GB VRAM を使う必要があります。
{% endhint %}

{% embed url="<https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/GLM_Flash_A100(80GB).ipynb>" %}

MoE のファインチューニングでは、ルーター層までファインチューニングするのはおそらく良くないので、既定では無効にしています。推論能力を維持したい場合（任意）、直接回答と Chain-of-Thought の例を混ぜて使えます。少なくとも <mark style="background-color:green;">75% の推論</mark> と <mark style="background-color:green;">25% の非推論</mark> をデータセットに含めて、モデルに推論能力を保持させてください。

### 🦙Llama-server の提供とデプロイ

本番環境で GLM-4.7-Flash をデプロイするには、次を使用します `llama-server` 新しいターミナルで、tmux などを使って、次の方法でモデルをデプロイします：

{% code overflow="wrap" %}

```bash
./llama.cpp/llama-server \\
    --model unsloth/GLM-4.7-Flash-GGUF/GLM-4.7-Flash-UD-Q4_K_XL.gguf \\
    --alias "unsloth/GLM-4.7-Flash" \\
    --seed 3407 \
    --temp 1.0 \\
    --top-p 0.95 \\
    --min-p 0.01 \
    --ctx-size 16384 \\
    --port 8001
```

{% endcode %}

その後、新しいターミナルで、次を行ってから `pip install openai`、次を実行します：

{% code overflow="wrap" %}

```python
from openai import OpenAI
import json
openai_client = OpenAI(
    base_url = "http://127.0.0.1:8001/v1",
    api_key = "sk-no-key-required",
)
completion = openai_client.chat.completions.create(
    model = "unsloth/GLM-4.7-Flash",
    messages = [{"role": "user", "content": "What is 2+2?"},],
)
print(completion.choices[0].message.content)
```

{% endcode %}

次が出力されます

{% code overflow="wrap" %}

```
ユーザーは「2+2 はいくつ？」という簡単な質問をしています。答えは4です。回答してください。

2 + 2 = 4.
```

{% endcode %}

### :computer: vLLM での GLM-4.7-Flash

現在は、新しい [FP8 動的量子化](https://huggingface.co/unsloth/GLM-4.7-Flash-FP8-Dynamic) を使って、このモデルを高品質かつ高速な推論に利用できます。まず nightly 版から vLLM をインストールしてください:

{% code overflow="wrap" %}

```bash
uv pip install --upgrade --force-reinstall vllm --torch-backend=auto --extra-index-url https://wheels.vllm.ai/nightly/cu130
uv pip install --upgrade --force-reinstall git+https://github.com/huggingface/transformers.git
uv pip install --force-reinstall numba
```

{% endcode %}

次に、 [Unsloth の動的 FP8 版](https://huggingface.co/unsloth/GLM-4.7-Flash-FP8-Dynamic) のモデルをサービングしてください。KV キャッシュのメモリ使用量を 50% 削減するために FP8 を有効化しており、4 GPU で動作します。1 GPU しかない場合は、次を使用してください `CUDA_VISIBLE_DEVICES='0'` そして、次を設定してください `--tensor-parallel-size 1` またはこの引数を削除してください。FP8 を無効にするには、 `--quantization fp8 --kv-cache-dtype fp8`

```bash
export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:False
CUDA_VISIBLE_DEVICES='0,1,2,3' vllm serve unsloth/GLM-4.7-Flash-FP8-Dynamic \
    --served-model-name unsloth/GLM-4.7-Flash \
    --tensor-parallel-size 4 \
    --tool-call-parser glm47 \
    --reasoning-parser glm45 \
    --enable-auto-tool-choice \
    --dtype bfloat16 \
    --seed 3407 \
    --max-model-len 200000 \
    --gpu-memory-utilization 0.95 \
    --max_num_batched_tokens 16384 \
    --port 8001 \
    --kv-cache-dtype fp8
```

その後、OpenAI API 経由で提供中のモデルを呼び出せます：

```python
from openai import AsyncOpenAI, OpenAI
openai_api_key = "EMPTY"
openai_api_base = "http://localhost:8001/v1"
client = OpenAI( # or AsyncOpenAI
    api_key=openai_api_key,
    base_url=openai_api_base,
)
```

#### :star: vLLM GLM-4.7-Flash の投機的デコード

GLM 4.7 Flash の MTP（マルチトークン予測）モジュールを使うと、生成スループットが 1 B200 あたり 13,000 トークンから 1,300 トークンに低下することがわかりました！(10倍遅い) Hopper では、おそらく問題ないはずです。

```bash
    --speculative-config.method mtp \
    --speculative-config.num_speculative_tokens 1
```

1xB200 ではスループットはわずか 1,300 トークン/秒（ユーザーごとのデコードは 130 トークン/秒）

<figure><img src="/files/e9c0874380c9e43e94bcb759d01b071abe829da6" alt=""><figcaption></figcaption></figure>

そして 1xB200 では 13,000 トークン/秒のスループット（それでもユーザーごとのデコードは 130 トークン/秒）

<figure><img src="/files/7249300cd1645f8602474c6d82c07d9ccfd4d5cb" alt=""><figcaption></figcaption></figure>

### :hammer:GLM-4.7-Flash によるツール呼び出し

参照 [Tool Calling Guide](/docs/jp/ji-ben/tool-calling-guide-for-local-llms.md) ツール呼び出しの方法の詳細については、こちらをご覧ください。新しいターミナルで（tmux を使っている場合は CTRL+B+D）、2つの数値を加算する、Python コードを実行する、Linux の関数を実行するなど、いくつかのツールを作成します：

{% code expandable="true" %}

```python
import json, subprocess, random
from typing import Any
def add_number(a: float | str, b: float | str) -> float:
    return float(a) + float(b)
def multiply_number(a: float | str, b: float | str) -> float:
    return float(a) * float(b)
def subtract_number(a: float | str, b: float | str) -> float:
    return float(a) - float(b)
def write_a_story() -> str:
    return random.choice([
        "はるか彼方の銀河系で、ずっと昔に……",
        "ナマケモノとコードが大好きな2人の友人がいました……",
        "すべてのナマケモノが超人的な知能を持つよう進化したため、世界は終わりを迎えつつありました……",
        "ある友人には知られぬまま、もう一人の友人がうっかりナマケモノを進化させるプログラムを書いていました……",
    ])
def terminal(command: str) -> str:
    if "rm" in command or "sudo" in command or "dd" in command or "chmod" in command:
        msg = "'rm, sudo, dd, chmod' コマンドは危険なため実行できません"
        print(msg); return msg
    print(f"ターミナルコマンド `{command}` を実行しています")
    try:
        return str(subprocess.run(command, capture_output = True, text = True, shell = True, check = True).stdout)
    except subprocess.CalledProcessError as e:
        return f"コマンドに失敗しました: {e.stderr}"
def python(code: str) -> str:
    data = {}
    exec(code, data)
    del data["__builtins__"]
    return str(data)
MAP_FN = {
    "add_number": add_number,
    "multiply_number": multiply_number,
    "subtract_number": subtract_number,
    "write_a_story": write_a_story,
    "terminal": terminal,
    "python": python,
}
tools = [
    {
        "type": "function",
        "function": {
            "name": "add_number",
            "description": "2つの数を加算します。",
            "parameters": {
                "type": "object",
                "properties": {
                    "a": {
                        "type": "string",
                        "description": "最初の数です。",
                    },
                    "b": {
                        "type": "string",
                        "description": "2番目の数です。",
                    },
                },
                "required": ["a", "b"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "multiply_number",
            "description": "2つの数を掛け算します。",
            "parameters": {
                "type": "object",
                "properties": {
                    "a": {
                        "type": "string",
                        "description": "最初の数です。",
                    },
                    "b": {
                        "type": "string",
                        "description": "2番目の数です。",
                    },
                },
                "required": ["a", "b"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "subtract_number",
            "description": "2つの数を引き算します。",
            "parameters": {
                "type": "object",
                "properties": {
                    "a": {
                        "type": "string",
                        "description": "最初の数です。",
                    },
                    "b": {
                        "type": "string",
                        "description": "2番目の数です。",
                    },
                },
                "required": ["a", "b"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "write_a_story",
            "description": "ランダムな物語を書きます。",
            "parameters": {
                "type": "object",
                "properties": {},
                "required": [],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "terminal",
            "description": "ターミナルから操作を実行します。",
            "parameters": {
                "type": "object",
                "properties": {
                    "command": {
                        "type": "string",
                        "description": "実行したいコマンドです。例: `ls`, `rm`, ...",
                    },
                },
                "required": ["command"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "python",
            "description": "実行する Python コードを使って Python インタープリタを呼び出します。",
            "parameters": {
                "type": "object",
                "properties": {
                    "code": {
                        "type": "string",
                        "description": "実行する Python コードです",
                    },
                },
                "required": ["code"],
            },
        },
    },
]
```

{% endcode %}

その後、以下の関数を使用します（コピーして貼り付けて実行してください）。これにより関数呼び出しを自動的に解析し、任意のモデルに対して OpenAI エンドポイントを呼び出します：

{% code overflow="wrap" expandable="true" %}

```python
from openai import OpenAI
def unsloth_inference(
    messages,
    temperature = 0.7,
    top_p = 1.0,
    top_k = -1,
    repetition_penalty = 0.0,
):
    messages = messages.copy()
    openai_client = OpenAI(
        base_url = "http://127.0.0.1:8001/v1",
        api_key = "sk-no-key-required",
    )
    model_name = next(iter(openai_client.models.list())).id
    print(f"使用モデル = {model_name}")
    has_tool_calls = True
    original_messages_len = len(messages)
    while has_tool_calls:
        print(f"現在のメッセージ = {messages}")
        response = openai_client.chat.completions.create(
            model = model_name,
            messages = messages,
            temperature = temperature,
            top_p = top_p,
            tools = tools if tools else None,
            tool_choice = "auto" if tools else None,
            extra_body = {"top_k": top_k, "min_p": min_p, "dry_multiplier" :repetition_penalty,}
        )
        tool_calls = response.choices[0].message.tool_calls or []
        content = response.choices[0].message.content or ""
        tool_calls_dict = [tc.to_dict() for tc in tool_calls] if tool_calls else tool_calls
        messages.append({"role": "assistant", "tool_calls": tool_calls_dict, "content": content,})
        for tool_call in tool_calls:
            fx, args, _id = tool_call.function.name, tool_call.function.arguments, tool_call.id
            out = MAP_FN[fx](**json.loads(args))
            messages.append({"role": "tool", "tool_call_id": _id, "name": fx, "content": str(out),})
        else:
            has_tool_calls = False
    return messages
```

{% endcode %}

次の方法で GLM-4.7-Flash を起動した後 `llama-server` 次のように [#deploy-with-llama-server-and-openais-completion-library](#deploy-with-llama-server-and-openais-completion-library "mention") または次を参照： [Tool Calling Guide](/docs/jp/ji-ben/tool-calling-guide-for-local-llms.md) 詳細については、その後いくつかのツール呼び出しを行えます：

**GLM 4.7 の数学演算用ツール呼び出し**

{% code overflow="wrap" %}

```python
messages = [{
    "role": "user",
    "content": [{"type": "text", "text": "今日は何日ですか。それに 3 日を足すと？"}],
}]
unsloth_inference(messages, temperature = 1.0, top_p = 0.95, top_k = -1, min_p = 0.01)
```

{% endcode %}

<figure><img src="/files/13169a592cccb180505dcd6371f3d293a096dc78" alt=""><figcaption></figcaption></figure>

**GLM-4.7-Flash で生成された Python コードを実行するツール呼び出し**

{% code overflow="wrap" %}

```python
messages = [{
    "role": "user",
    "content": [{"type": "text", "text": "Python でフィボナッチ関数を作成し、fib(20) を求めてください。"}],
}]
unsloth_inference(messages, temperature = 1.0, top_p = 0.95, top_k = -1, min_p = 0.01)
```

{% endcode %}

<figure><img src="/files/2ceb7043fd1f9573d24a2d44261488b25e60c960" alt="" width="563"><figcaption></figcaption></figure>

### ベンチマーク

GLM-4.7-Flash は、AIME 25 を除くすべてのベンチマークで最も高性能な 30B モデルです。

<figure><img src="/files/b8660b7d2b877fea77db231c70e0526345ed4988" alt="" width="375"><figcaption></figcaption></figure>

| ベンチマーク             | GLM-4.7-Flash | Qwen3-30B-A3B-Thinking-2507 | GPT-OSS-20B |
| ------------------ | ------------- | --------------------------- | ----------- |
| AIME 25            | 91.6          | 85.0                        | 91.7        |
| GPQA               | 75.2          | 73.4                        | 71.5        |
| LCB v6             | 64.0          | 66.0                        | 61.0        |
| HLE                | 14.4          | 9.8                         | 10.9        |
| SWE-bench Verified | 59.2          | 22.0                        | 34.0        |
| τ²-Bench           | 79.5          | 49.0                        | 47.7        |
| BrowseComp         | 42.8          | 2.29                        | 28.3        |


---

# 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 dynamically by asking a question.

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

```
GET https://unsloth.ai/docs/jp/moderu/tutorials/glm-4.7-flash.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
