> 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をローカル実行・ファインチューニングしましょう！

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 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 を無効にするのを忘れないでください！ または、** `--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 を無効にするのを忘れないでください！ または、** `--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) + **web search**
* [**コード実行**](/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="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FFeQ0UUlnjXkDdqhcWglh%2Fskinny%20studio%20chat.png?alt=media&amp;token=c2ee045f-c243-4024-a8e4-bb4dbe7bae79" 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="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2F4oQKFbYhEz7h2K9H3EuP%2FScreenshot%202026-04-02%20at%201.59.45%E2%80%AFAM.png?alt=media&amp;token=bf78de14-cbcb-4f99-b9b4-65a500a6dd20" 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="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FXPQGEEr1YoKofrTatAKK%2Ftoolcallingif.gif?alt=media&amp;token=25d68698-fb13-4c46-99b2-d39fb025df08" alt="" width="563"><figcaption></figcaption></figure></div>
{% endstep %}
{% endstepper %}

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

llama.cpp で実行する手順（ほとんどのデバイスに収めるため、4bit を使用します）：

{% 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`
* **repeat penalty を無効にするのを忘れないでください！**

これに従ってください: **一般的な手順** ユースケース:

```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-chu/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 を無効にするのを忘れないでください！ または、** `--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 ファイルで作って
バグを見つけて修正済みのゲームを表示して
```

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

<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 Fixed</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>タップするか Space キーで開始</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) {
                // 垂直方向の重なり（上のパイプに当たる OR 下のパイプに当たる）
                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="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FJ85uzHPDWinaXPe6kWyU%2Fimage.png?alt=media&amp;token=6547f49d-2544-4c48-a7d5-5c1c67d34a87" alt="" width="188"><figcaption></figcaption></figure> <figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FHAc2SjNLo1OsyAC4dArm%2Fimage.png?alt=media&amp;token=87d4bfea-4ac9-41ef-be1c-1e51664d30b1" 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": "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 quant](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="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FCJPJYh1uIS1yL8vskiOF%2Fimage.png?alt=media&amp;token=f07aaad9-93bd-4507-836f-967a3d39b0e5" alt=""><figcaption></figcaption></figure>

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

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FrXaHEknUb1QW1v0arO0q%2Fimage.png?alt=media&amp;token=dd81b731-90bb-4d1b-a647-a64618f5952a" alt=""><figcaption></figcaption></figure>

### :hammer:GLM-4.7-Flash でのツール呼び出し

こちらを参照 [Tool Calling Guide](/docs/jp/ji-chu/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"Executing terminal command `{command}`")
    try:
        return str(subprocess.run(command, capture_output = True, text = True, shell = True, check = True).stdout)
    except subprocess.CalledProcessError as e:
        return f"Command failed: {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"Using model = {model_name}")
    has_tool_calls = True
    original_messages_len = len(messages)
    while has_tool_calls:
        print(f"Current messages = {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-chu/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="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FoFkZ20QOSGdzT4iz2SOB%2Fimage.png?alt=media&amp;token=e4ca30b0-dcec-4a26-b019-dd33f0600949" 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="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FhS8sWtZwjwerElezCc2C%2Fimage.png?alt=media&amp;token=39032ef8-386e-4837-8dd2-c552c80a3ee3" alt="" width="563"><figcaption></figcaption></figure>

### ベンチマーク

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

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FuU8GDqR2ni6slcQ1pWzL%2Fglm4.7%20benchmarks.jpg?alt=media&amp;token=1f609b73-c20b-4e4c-bbf8-0e7213c00b44" 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 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/glm-4.7-flash.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.
