> 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 推論モデルで、ローカルデプロイ向けに構築されており、コーディング、エージェント型ワークフロー、チャットでクラス最高の性能を発揮します。約 3.6B パラメータを使用し、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 Verified                                 |
| ------------------------------------------------------------------ | ------------------------------------------------------------------ |
| <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>      |
| repeat penalty = 無効または 1.0                                         | repeat penalty = 無効または 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）
* [自動推論](/docs/jp/shii/studio.md#model-arena) パラメータ調整（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 を使って実行しました。 `./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 ファイルとして作成して
バグを見つけて修正済みのゲームを表示して
```

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

<details>

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

```html
<!DOCTYPE html>
<html lang="ja">
<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>GAME OVER</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 のファインチューニングでは、ルーター層をファインチューニングするのはおそらく良くないので、デフォルトで無効にしています。推論能力を維持したい場合（任意）は、直接回答と CoT 例を混ぜて使えます。少なくとも <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 Dynamic 量子化版](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( # または 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.
