> 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/zh/mo-xing/tutorials/glm-4.7-flash.md).

# GLM-4.7-Flash：如何本地运行

GLM-4.7-Flash 是 Z.ai 新推出的 30B MoE 推理模型，专为本地部署而打造，在编码、智能体工作流和聊天方面提供同类最佳的性能。它使用约 36 亿参数，支持 20 万上下文，并在 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/a63fe18206ba278e17e40bf31ce577cda524869c#run-glm-4.7-flash" class="button primary">运行教程</a><a href="/pages/a63fe18206ba278e17e40bf31ce577cda524869c#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>      |
| 重复惩罚 = 禁用或 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" %}
目前，我们 **不建议** 使用 **Ollama** 运行这个 GGUF，因为可能存在聊天模板兼容性问题。该 GGUF 在 llama.cpp（或诸如 LM Studio、Jan 等后端）上运行良好。

**记得禁用重复惩罚！或者设置** `--repeat-penalty 1.0`
{% endhint %}

* **最大上下文窗口：** `202,752`

### 🖥️ 运行 GLM-4.7-Flash

根据你的用例，你需要使用不同的设置。某些 GGUF 的大小最终会相近，因为模型架构（如 [gpt-oss](/docs/zh/mo-xing/gpt-oss-how-to-run-and-fine-tune.md)）的维度不能被 128 整除，因此部分无法量化到更低比特。

由于本指南使用 4-bit，你将需要大约 18GB RAM/统一内存。为了获得最佳性能，我们建议至少使用 4-bit 精度。

{% hint style="warning" %}
目前，我们 **不建议** 使用 **Ollama** 运行这个 GGUF，因为可能存在聊天模板兼容性问题。该 GGUF 在 llama.cpp（或诸如 LM Studio、Jan 等后端）上运行良好。

**记得禁用重复惩罚！或者设置** `--repeat-penalty 1.0`
{% endhint %}

#### 🦥 Unsloth Studio 指南

GLM-4.7-Flash 可以在 [Unsloth Studio](/docs/zh/xin/studio.md)，这是我们新的本地 AI 开源 Web UI。借助 Unsloth Studio，你可以在本地运行模型，支持 **MacOS、Windows**、Linux 以及：

{% columns %}
{% column %}

* 搜索、下载、 [运行 GGUF](/docs/zh/xin/studio.md#run-models-locally) 和 safetensor 模型
* [**自我修复** 工具调用](/docs/zh/xin/studio.md#execute-code--heal-tool-calling) + **网页搜索**
* [**代码执行**](/docs/zh/xin/studio.md#run-models-locally) （Python、Bash）
* [自动推理](https://unsloth.ai/docs/desktop#feature-deep-dive) 参数调优（temp、top-p 等）
* 通过 llama.cpp 实现快速 CPU + GPU 推理
* [训练 LLM](/docs/zh/xin/studio.md#no-code-training) 速度快 2 倍，VRAM 占用减少 70%
  {% endcolumn %}

{% column %}

<div data-with-frame="true"><figure><img src="/files/5af4df407c8134f1ff75a4d7535569361c049e51" 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/zh/xin/studio/chat.md) 选项卡并搜索 **GLM-4.7-Flash** 输入到搜索栏，并下载你想要的模型和量化版本。

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

{% step %}
**运行 GLM-4.7-Flash**

在使用 Unsloth Studio 时，推理参数应会自动设置，不过你仍然可以手动更改。你也可以编辑上下文长度、聊天模板和其他设置。

更多信息请查看我们的 [Unsloth Studio 推理指南](/docs/zh/xin/studio/chat.md).

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

#### Llama.cpp 教程（GGUF）：

在 llama.cpp 中运行的说明（注意我们将使用 4-bit，以适配大多数设备）：

{% 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 的允许情况将上下文增加到 20 万。

你也可以尝试 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/zh/ji-chu-zhi-shi/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" %}
目前，我们 **不建议** 使用 **Ollama** 运行这个 GGUF，因为可能存在聊天模板兼容性问题。该 GGUF 在 llama.cpp（或诸如 LM Studio、Jan 等后端）上运行良好。
{% endhint %}

### :bird:使用 UD-Q4\_K\_XL 的 Flappy Bird 示例

例如，我们通过 `./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 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>点击或按空格键开始</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/d767b0a57bd3a9c5931cf07dfd66b818c4fc1297" alt="" width="188"><figcaption></figcaption></figure> <figure><img src="/files/c867f0e944e7d9329c98fb1d85b76d1588c567c8" alt="" width="188"><figcaption></figcaption></figure></div>

### 🦥 微调 GLM-4.7-Flash

Unsloth 现在支持对 GLM-4.7-Flash 进行微调，不过你需要使用 `transformers v5`. 30B 模型无法装入免费的 Colab GPU；不过你可以使用我们的 notebook。GLM-4.7-Flash 的 16-bit LoRA 微调将使用大约 **60GB VRAM**:

* [GLM-4.7-Flash SFT LoRA notebook](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 时，微调路由层可能不是个好主意，所以我们默认禁用了它。如果你想保留其推理能力（可选），可以使用直接答案和思维链示例的混合。至少使用 <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 动态量化](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) 的模型。我们启用了 FP8，以将 KV cache 内存使用减少 50%，并在 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（多 token 预测）模块会使生成吞吐量从 1 个 B200 上的 13,000 tokens 降到 1,300 tokens！(慢 10 倍) 在 Hopper 上，希望应该没问题。

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

在 1xB200 上吞吐量只有 1,300 tokens/s（每个用户的解码速度为 130 tokens/s）

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

而在 1xB200 上吞吐量为 13,000 tokens/s（每个用户的解码速度仍为 130 tokens/s）

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

### :hammer:使用 GLM-4.7-Flash 的工具调用

参见 [Tool Calling Guide](/docs/zh/ji-chu-zhi-shi/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([
        "很久很久以前，在一个遥远遥远的星系里...",
        "有两个朋友热爱树懒和代码...",
        "因为每只树懒都进化出了超人般的智慧，世界正在走向终结...",
        "其中一个朋友并不知道，另一个朋友不小心写了一个让树懒进化的程序...",
    ])
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": "添加两个数字。",
            "parameters": {
                "type": "object",
                "properties": {
                    "a": {
                        "type": "string",
                        "description": "第一个数字。",
                    },
                    "b": {
                        "type": "string",
                        "description": "第二个数字。",
                    },
                },
                "required": ["a", "b"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "multiply_number",
            "description": "将两个数字相乘。",
            "parameters": {
                "type": "object",
                "properties": {
                    "a": {
                        "type": "string",
                        "description": "第一个数字。",
                    },
                    "b": {
                        "type": "string",
                        "description": "第二个数字。",
                    },
                },
                "required": ["a", "b"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "subtract_number",
            "description": "将两个数字相减。",
            "parameters": {
                "type": "object",
                "properties": {
                    "a": {
                        "type": "string",
                        "description": "第一个数字。",
                    },
                    "b": {
                        "type": "string",
                        "description": "第二个数字。",
                    },
                },
                "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/zh/ji-chu-zhi-shi/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/709a7caf90f687c85c658d21f595e0be8beb2b73" 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/0b229e56ef0ba6e1bd20edfed3c3cf4b69331bf4" alt="" width="563"><figcaption></figcaption></figure>

### 基准测试

GLM-4.7-Flash 是除 AIME 25 外所有基准测试中表现最好的 30B 模型。

<figure><img src="/files/751e105423da5bbb021c69aef5dd8936e902c50a" 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/zh/mo-xing/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.
