# GLM-5 : guide d'exécution locale

GLM-5 est le dernier modèle de raisonnement de Z.ai, offrant de meilleures performances en codage, en agents et en chat que [GLM-4.7](https://unsloth.ai/docs/fr/modeles/tutorials/glm-4.7), et il est conçu pour le raisonnement sur long contexte. Il améliore les performances sur des benchmarks tels que Humanity's Last Exam avec 50.4 % (+7.6 %), BrowseComp avec 75.9 % (+8.4 %) et Terminal-Bench-2.0 avec 61.1 % (+28.3 %).

Le modèle complet de 744B paramètres (40B actifs) dispose d'une **fenêtre de contexte de 200K** et a été préentraîné sur 28.5T tokens. Le modèle complet GLM-5 nécessite **1.65TB** d'espace disque, tandis que le Unsloth Dynamic 2-bit GGUF réduit la taille à **241GB** **(-85%)**, et le dynamic **1-bit fait 176GB (-89 %) :** [**GLM-5-GGUF**](https://huggingface.co/unsloth/GLM-5-GGUF)

Tous les téléversements utilisent Unsloth [Dynamic 2.0](https://unsloth.ai/docs/fr/bases/unsloth-dynamic-2.0-ggufs) pour des performances de quantification SOTA - ainsi, le 1-bit voit ses couches importantes remontées en 8 ou 16-bit. Merci à Z.ai d'avoir fourni à Unsloth un accès day zero.

### :gear: Guide d'utilisation

La quantification dynamique 2-bit UD-IQ2\_XXS utilise **241GB** d'espace disque - cela peut tenir directement sur un **Mac avec mémoire unifiée de 256GB**, et fonctionne aussi bien sur **une carte 1x24GB et 256GB de RAM** avec déchargement MoE. Le **1-bit** quant tient sur 180GB de RAM et le 8-bit nécessite 805GB de RAM.

{% hint style="success" %}
Pour de meilleures performances, assurez-vous que votre mémoire totale disponible (VRAM + RAM système) dépasse la taille du fichier du modèle quantifié que vous téléchargez. Sinon, llama.cpp peut toujours fonctionner via le déchargement SSD/HDD, mais l'inférence sera plus lente.
{% endhint %}

### Paramètres recommandés

Utilisez des paramètres distincts pour différents cas d'utilisation :

| Paramètres par défaut (la plupart des tâches) | SWE Bench Verified                 |
| --------------------------------------------- | ---------------------------------- |
| temperature = 1.0                             | temperature = 0.7                  |
| top\_p = 0.95                                 | top\_p = 1.0                       |
| max new tokens = 131072                       | max new tokens = 16384             |
| repeat penalty = désactivée ou 1.0            | repeat penalty = désactivée ou 1.0 |

* `Min_P = 0.01` (la valeur par défaut de llama.cpp est 0.05)
* **Fenêtre de contexte maximale :** `202,752`.
* Pour les tâches agentiques multi-tours (τ²-Bench et Terminal Bench 2), veuillez activer le mode Pensée préservée.<br>

## Lancer les tutoriels GLM-5 :

#### ✨ Exécuter dans llama.cpp

{% stepper %}
{% step %}
Obtenez la dernière version de `llama.cpp` **sur** [**GitHub ici**](https://github.com/ggml-org/llama.cpp). Vous pouvez aussi suivre les instructions de compilation ci-dessous. Remplacez `-DGGML_CUDA=ON` par `-DGGML_CUDA=OFF` si vous n'avez pas de GPU ou si vous souhaitez simplement une inférence CPU. **Pour les appareils Apple Mac / Metal**, définissez `-DGGML_CUDA=OFF` puis continuez normalement - la prise en charge de Metal est activée par défaut.

```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
```

{% endstep %}

{% step %}
Si vous souhaitez utiliser `llama.cpp` directement pour charger des modèles, vous pouvez faire ce qui suit : (:IQ2\_XXS) est le type de quantification. Vous pouvez aussi télécharger via Hugging Face (point 3). C'est similaire à `ollama run` . Utilisez `export LLAMA_CACHE="folder"` pour forcer `llama.cpp` l'enregistrement dans un emplacement spécifique. N'oubliez pas que le modèle n'a qu'une longueur de contexte maximale de 200K.

Suivez ceci pour les cas d'utilisation de **instructions générales**  :

```bash
export LLAMA_CACHE="unsloth/GLM-5-GGUF"
./llama.cpp/llama-cli \
    -hf unsloth/GLM-5-GGUF:UD-IQ2_XXS \
    --ctx-size 16384 \
    --flash-attn on \
    --temp 0.7 \
    --top-p 1.0 \
    --min-p 0.01
```

Suivez ceci pour les cas d'utilisation de **appel d'outils**  :

```bash
export LLAMA_CACHE="unsloth/GLM-5-GGUF"
./llama.cpp/llama-cli \
    -hf unsloth/GLM-5-GGUF:UD-IQ2_XXS \
    --ctx-size 16384 \
    --flash-attn on \
    --temp 1.0 \
    --top-p 0.95 \
    --min-p 0.01
```

{% endstep %}

{% step %}
Téléchargez le modèle via (après avoir installé `pip install huggingface_hub hf_transfer` ). Vous pouvez choisir `UD-Q2_K_XL` (quantification dynamique 2 bits) ou d'autres versions quantifiées comme `UD-Q4_K_XL` . Nous <mark style="background-color:green;">**recommandons d'utiliser notre quantification dynamique 2 bits**</mark><mark style="background-color:green;">**&#x20;**</mark><mark style="background-color:green;">**`UD-Q2_K_XL`**</mark><mark style="background-color:green;">**&#x20;**</mark><mark style="background-color:green;">**pour équilibrer taille et précision**</mark>. Si les téléchargements se bloquent, voir [hugging-face-hub-xet-debugging](https://unsloth.ai/docs/fr/bases/troubleshooting-and-faqs/hugging-face-hub-xet-debugging "mention")

```bash
pip install -U huggingface_hub
hf download unsloth/GLM-5-GGUF \
    --local-dir unsloth/GLM-5-GGUF \
    --include "*UD-IQ2_XXS*" # Utilisez "*UD-TQ1_0*" pour le 1-bit dynamique
```

{% endstep %}

{% step %}
Vous pouvez modifier `--threads 32` pour le nombre de threads CPU, `--ctx-size 16384` pour la longueur du contexte, `--n-gpu-layers 2` pour le déchargement GPU, selon le nombre de couches. Essayez d'ajuster ce paramètre si votre GPU manque de mémoire. Supprimez-le également si vous n'avez qu'une inférence CPU.

{% code overflow="wrap" %}

```bash
./llama.cpp/llama-cli \
    --model unsloth/GLM-5-GGUF/UD-IQ2_XXS/GLM-5-UD-IQ2_XXS-00001-of-00006.gguf \
    --temp 1.0 \
    --top-p 0.95 \
    --min-p 0.01 \
    --ctx-size 16384 \
    --seed 3407
```

{% endcode %}
{% endstep %}
{% endstepper %}

### 🦙 Serveur Llama et bibliothèque de complétion d'OpenAI

Pour déployer GLM-5 en production, nous utilisons `llama-server` Dans un nouveau terminal, par exemple via tmux, déployez le modèle avec :

{% code overflow="wrap" %}

```bash
./llama.cpp/llama-server \
    --model unsloth/GLM-5-GGUF/UD-IQ2_XXS/GLM-5-UD-IQ2_XXS-00001-of-00006.gguf \
    --alias "unsloth/GLM-5" \
    --prio 3 \
    --temp 1.0 \
    --top-p 0.95 \
    --ctx-size 16384 \
    --port 8001
```

{% endcode %}

Puis, dans un nouveau terminal, après avoir effectué `pip install openai`, faites :

{% 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-5",
    messages = [{"role": "user", "content": "Créer un jeu Snake."},],
)
print(completion.choices[0].message.content)
```

{% endcode %}

Et vous obtiendrez l'exemple suivant d'un jeu Snake :

{% columns %}
{% column width="58.333333333333336%" %}
{% code expandable="true" %}

````markdown
Voici un jeu Snake complet et jouable contenu dans un seul fichier HTML. Vous pouvez copier ce code, l'enregistrer dans un fichier `.html` (par exemple `snake.html`), puis l'ouvrir dans votre navigateur web pour jouer.

### Le code

```html
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Jeu classique Snake</title>
    <style>
        body {
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #222;
            color: white;
            font-family: Arial, sans-serif;
        }

        #gameCanvas {
            border: 2px solid #fff;
            background-color: #000;
        }

        h1 {
            margin-bottom: 10px;
        }

        #scoreBoard {
            font-size: 20px;
            margin-bottom: 10px;
        }

        #gameOverMenu {
            position: absolute;
            display: none;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            background: rgba(0, 0, 0, 0.85);
            padding: 20px;
            border-radius: 10px;
            border: 2px solid red;
        }

        button {
            margin-top: 15px;
            padding: 10px 20px;
            font-size: 16px;
            cursor: pointer;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 5px;
        }
        
        button:hover {
            background-color: #45a049;
        }
    </style>
</head>
<body>

    <h1>Jeu Snake</h1>
    <div id="scoreBoard">Score : 0</div>
    <canvas id="gameCanvas" width="400" height="400"></canvas>

    <div id="gameOverMenu">
        <h2 style="color: red; margin: 0;">Partie terminée !</h2>
        <p id="finalScore">Score final : 0</p>
        <button onclick="resetGame()">Rejouer</button>
    </div>

    <script>
        // Constantes du jeu
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const scoreBoard = document.getElementById('scoreBoard');
        const gameOverMenu = document.getElementById('gameOverMenu');
        const finalScoreDisplay = document.getElementById('finalScore');

        const gridSize = 20; // Taille de chaque carré
        const tileCount = canvas.width / gridSize; // Nombre de carrés par ligne/colonne

        // Variables du jeu
        let dx = 0; // Vitesse horizontale
        let dy = 0; // Vitesse verticale
        let score = 0;
        let snake = [];
        let foodX, foodY;
        let gameInterval;
        let isGameRunning = false;

        // Initialiser le jeu
        function initGame() {
            snake = [
                {x: 10, y: 10}, 
                {x: 9, y: 10}, 
                {x: 8, y: 10}
            ];
            score = 0;
            scoreBoard.innerText = 'Score : ' + score;
            dx = 1; // Commence à se déplacer vers la droite immédiatement
            dy = 0;
            placeFood();
            isGameRunning = true;
            gameOverMenu.style.display = 'none';
            
            // Démarrer la boucle du jeu
            if (gameInterval) clearInterval(gameInterval);
            gameInterval = setInterval(gameLoop, 100); // Exécute la boucle du jeu toutes les 100 ms
        }

        // Boucle principale du jeu
        function gameLoop() {
            if (!isGameRunning) return;

            moveSnake();
            if (checkGameOver()) {
                endGame();
                return;
            }
            checkFoodCollision();
            draw();
        }

        // Déplacer le serpent
        function moveSnake() {
            // Créer une nouvelle tête selon la direction actuelle
            const head = {x: snake[0].x + dx, y: snake[0].y + dy};
            
            // Ajouter la nouvelle tête au début du tableau
            snake.unshift(head);

            // Retirer la queue (dernier élément) sauf si la nourriture est mangée
            // Remarque : nous gérons la suppression de la queue dans checkFoodCollision
            snake.pop(); 
        }

        // Vérifier si le serpent mange la nourriture
        function checkFoodCollision() {
            const head = snake[0];
            
            if (head.x === foodX && head.y === foodY) {
                // Faire grandir le serpent : ajouter un morceau de queue (dupliquer le dernier)
                snake.push({...snake[snake.length - 1]});
                score += 10;
                scoreBoard.innerText = 'Score : ' + score;
                placeFood();
            }
        }

        // Vérifier les collisions (murs ou soi-même)
        function checkGameOver() {
            const head = snake[0];

            // Collision avec le mur
            if (head.x < 0 || head.x >= tileCount || head.y < 0 || head.y >= tileCount) {
                return true;
            }

            // Collision avec soi-même (commencer la vérification à partir du 4e segment car la tête ne peut pas toucher les 3 premiers)
            for (let i = 4; i < snake.length; i++) {
                if (head.x === snake[i].x && head.y === snake[i].y) {
                    return true;
                }
            }

            return false;
        }

        // Dessiner tout
        function draw() {
            // Effacer le canevas
            ctx.fillStyle = 'black';
            ctx.fillRect(0, 0, canvas.width, canvas.height);

            // Dessiner la nourriture
            ctx.fillStyle = 'red';
            ctx.fillRect(foodX * gridSize, foodY * gridSize, gridSize - 2, gridSize - 2);

            // Dessiner le serpent
            ctx.fillStyle = 'lime';
            for (let i = 0; i < snake.length; i++) {
                // Dessiner la tête un peu différemment ou simplement de manière standard
                const part = snake[i];
                ctx.fillRect(part.x * gridSize, part.y * gridSize, gridSize - 2, gridSize - 2);
            }
        }

        // Placer la nourriture à une position aléatoire
        function placeFood() {
            foodX = Math.floor(Math.random() * tileCount);
            foodY = Math.floor(Math.random() * tileCount);

            // S'assurer que la nourriture n'apparaît pas sur le corps du serpent
            for (let part of snake) {
                if (part.x === foodX && part.y === foodY) {
                    placeFood(); // Trouver récursivement un nouvel emplacement
                    return;
                }
            }
        }

        // Logique de fin de partie
        function endGame() {
            isGameRunning = false;
            clearInterval(gameInterval);
            finalScoreDisplay.innerText = 'Score final : ' + score;
            gameOverMenu.style.display = 'flex';
        }

        // Logique de réinitialisation du jeu
        function resetGame() {
            initGame();
        }

        // Contrôles clavier
        document.addEventListener('keydown', (e) => {
            // Empêcher d'inverser la direction (on ne peut pas aller à gauche si l'on va à droite)
            switch(e.key) {
                case 'ArrowUp':
                    if (dy !== 1) { dx = 0; dy = -1; }
                    break;
                case 'ArrowDown':
                    if (dy !== -1) { dx = 0; dy = 1; }
                    break;
                case 'ArrowLeft':
                    if (dx !== 1) { dx = -1; dy = 0; }
                    break;
                case 'ArrowRight':
                    if (dx !== -1) { dx = 1; dy = 0; }
                    break;
                case ' ':
                    if (!isGameRunning && gameOverMenu.style.display !== 'flex') {
                        initGame();
                    }
                    break;
            }
        });

        // Démarrer le jeu au chargement
        initGame();
    </script>
</body>
</html>
```

### Comment jouer
1.  **Copiez le code** ci-dessus.
2.  Créez un nouveau fichier sur votre ordinateur nommé `snake.html`.
3.  **Collez le code** dans ce fichier et enregistrez-le.
4.  **Double-cliquez sur `snake.html`** pour l'ouvrir dans votre navigateur.

### Commandes
*   **Flèches directionnelles** : déplacer vers le haut, le bas, la gauche, la droite.
*   **Barre d'espace** : démarre le jeu (s'il n'a pas encore commencé).
*   **Bouton Rejouer** : apparaît lorsque vous perdez pour redémarrer la partie.

### Fonctionnalités de cette version
*   **Déplacement sur grille** : sensation rétro classique.
*   **Suivi du score** : mise à jour en temps réel.
*   **Écran de fin de partie** : affiche votre score final et vous permet de redémarrer facilement.
*   **Détection des collisions** : met fin à la partie si vous heurtez les murs ou vous-même.
*   **Sécurité contre l'auto-collision** : le code empêche le serpent de se manger accidentellement immédiatement après avoir mangé de la nourriture, en raison de la logique de « saut de queue » couramment utilisée dans les tutoriels simples.
````

{% endcode %}
{% endcolumn %}

{% column width="41.666666666666664%" %}

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FsdUp9wbpqDx0Lhp00xZ0%2Fimage.png?alt=media&#x26;token=a5e67ac2-65bf-43e0-8c13-4aef9a7d269e" alt=""><figcaption></figcaption></figure>
{% endcolumn %}
{% endcolumns %}

### :computer: Déploiement vLLM

Vous pouvez maintenant servir la version FP8 du modèle de Z.ai via vLLM. Vous avez besoin de 860GB de VRAM ou plus, donc 8xH200 (141x8 = 1128GB) est au minimum recommandé. 8xB200 fonctionne bien. Tout d'abord, installez la version nightly de 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 %}

Pour désactiver le cache KV FP8 (réduit l'utilisation mémoire de 50 %), supprimez `--kv-cache-dtype fp8`

```bash
export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:False
vllm serve unsloth/GLM-5-FP8 \
    --served-model-name unsloth/GLM-5-FP8 \ \
    --kv-cache-dtype fp8 \
    --tensor-parallel-size 8 \
    --tool-call-parser glm47 \
    --reasoning-parser glm45 \
    --enable-auto-tool-choice \
    --dtype bfloat16 \
    --seed 3407 \
    --max-model-len 200000 \
    --gpu-memory-utilization 0.93 \
    --max_num_batched_tokens 4096 \
    --speculative-config.method mtp \
    --speculative-config.num_speculative_tokens 1 \
    --port 8001
```

Vous pouvez ensuite appeler le modèle servi via l'API OpenAI :

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

### :hammer:Appel d'outils avec GLM 5

Voir [tool-calling-guide-for-local-llms](https://unsloth.ai/docs/fr/bases/tool-calling-guide-for-local-llms "mention") pour plus de détails sur la manière de faire de l'appel d'outils. Dans un nouveau terminal (si vous utilisez tmux, utilisez CTRL+B+D), nous créons quelques outils comme l'addition de 2 nombres, l'exécution de code Python, l'exécution de fonctions Linux, et bien plus encore :

{% 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 substract_number(a: float | str, b: float | str) -> float:
    return float(a) - float(b)
def write_a_story() -> str:
    return random.choice([
        "Il était une fois, dans une galaxie très très lointaine...",
        "Il y avait 2 amis qui aimaient les paresseux et le code...",
        "Le monde touchait à sa fin parce que chaque paresseux avait évolué pour posséder une intelligence surhumaine...",
        "À l'insu de l'un des amis, l'autre a accidentellement codé un programme pour faire évoluer les paresseux...",
    ])
def terminal(command: str) -> str:
    if "rm" in command or "sudo" in command or "dd" in command or "chmod" in command:
        msg = "Cannot execute 'rm, sudo, dd, chmod' commands since they are dangerous"
        print(msg); return msg
    print(f"Exécution de la commande terminal `{command}`")
    try:
        return str(subprocess.run(command, capture_output = True, text = True, shell = True, check = True).stdout)
    except subprocess.CalledProcessError as e:
        return f"Échec de la commande : {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,
    "substract_number": substract_number,
    "write_a_story": write_a_story,
    "terminal": terminal,
    "python": python,
}
tools = [
    {
        "type": "function",
        "function": {
            "name": "add_number",
            "description": "Additionner deux nombres.",
            "parameters": {
                "type": "object",
                "properties": {
                    "a": {
                        "type": "string",
                        "description": "Le premier nombre.",
                    },
                    "b": {
                        "type": "string",
                        "description": "Le second nombre.",
                    },
                },
                "required": ["a", "b"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "multiply_number",
            "description": "Multiplier deux nombres.",
            "parameters": {
                "type": "object",
                "properties": {
                    "a": {
                        "type": "string",
                        "description": "Le premier nombre.",
                    },
                    "b": {
                        "type": "string",
                        "description": "Le second nombre.",
                    },
                },
                "required": ["a", "b"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "substract_number",
            "description": "Soustraire deux nombres.",
            "parameters": {
                "type": "object",
                "properties": {
                    "a": {
                        "type": "string",
                        "description": "Le premier nombre.",
                    },
                    "b": {
                        "type": "string",
                        "description": "Le second nombre.",
                    },
                },
                "required": ["a", "b"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "write_a_story",
            "description": "Écrit une histoire aléatoire.",
            "parameters": {
                "type": "object",
                "properties": {},
                "required": [],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "terminal",
            "description": "Effectue des opérations depuis le terminal.",
            "parameters": {
                "type": "object",
                "properties": {
                    "command": {
                        "type": "string",
                        "description": "La commande que vous souhaitez lancer, par ex. `ls`, `rm`, ...",
                    },
                },
                "required": ["command"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "python",
            "description": "Appelle un interpréteur Python avec du code Python qui sera exécuté.",
            "parameters": {
                "type": "object",
                "properties": {
                    "code": {
                        "type": "string",
                        "description": "Le code Python à exécuter",
                    },
                },
                "required": ["code"],
            },
        },
    },
]
```

{% endcode %}

Nous utilisons ensuite les fonctions ci-dessous (copiez-collez et exécutez) qui analyseront automatiquement les appels de fonction et appelleront le point de terminaison OpenAI pour n'importe quel modèle :

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

```python
from openai import OpenAI
def unsloth_inference(
    messages,
    temperature = 1.0,
    top_p = 0.95,
    top_k = -1,
    min_p = 0.01,
    repetition_penalty = 1.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, "repetition_penalty" :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 %}

Après le lancement de GLM 5 via `llama-server` comme dans [#deploy-with-llama-server-and-openais-completion-library](#deploy-with-llama-server-and-openais-completion-library "mention") ou voir [tool-calling-guide-for-local-llms](https://unsloth.ai/docs/fr/bases/tool-calling-guide-for-local-llms "mention") pour plus de détails, nous pouvons ensuite effectuer des appels d'outils.

### 📊 Benchmarks

Vous pouvez voir ci-dessous les benchmarks sous forme de tableau :

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2F3QI8akFZoQFXsZ2ojtgK%2Fglm5%20bench.jpg?alt=media&#x26;token=0fb5d73f-4dc4-46f5-bd76-206c26ff5e96" alt="" width="375"><figcaption></figcaption></figure>

<table data-full-width="true"><thead><tr><th>Benchmark</th><th>GLM-5</th><th>GLM-4.7</th><th>DeepSeek-V3.2</th><th>Kimi K2.5</th><th>Claude Opus 4.5</th><th>Gemini 3 Pro</th><th>GPT-5.2 (xhigh)</th></tr></thead><tbody><tr><td>HLE</td><td>30.5</td><td>24.8</td><td>25.1</td><td>31.5</td><td>28.4</td><td>37.2</td><td>35.4</td></tr><tr><td>HLE (avec outils)</td><td>50.4</td><td>42.8</td><td>40.8</td><td>51.8</td><td>43.4*</td><td>45.8*</td><td>45.5*</td></tr><tr><td>AIME 2026 I</td><td>92.7</td><td>92.9</td><td>92.7</td><td>92.5</td><td>93.3</td><td>90.6</td><td>-</td></tr><tr><td>HMMT nov. 2025</td><td>96.9</td><td>93.5</td><td>90.2</td><td>91.1</td><td>91.7</td><td>93.0</td><td>97.1</td></tr><tr><td>IMOAnswerBench</td><td>82.5</td><td>82.0</td><td>78.3</td><td>81.8</td><td>78.5</td><td>83.3</td><td>86.3</td></tr><tr><td>GPQA-Diamond</td><td>86.0</td><td>85.7</td><td>82.4</td><td>87.6</td><td>87.0</td><td>91.9</td><td>92.4</td></tr><tr><td>SWE-bench Verified</td><td>77.8</td><td>73.8</td><td>73.1</td><td>76.8</td><td>80.9</td><td>76.2</td><td>80.0</td></tr><tr><td>SWE-bench Multilingual</td><td>73.3</td><td>66.7</td><td>70.2</td><td>73.0</td><td>77.5</td><td>65.0</td><td>72.0</td></tr><tr><td>Terminal-Bench 2.0 (Terminus 2)</td><td>56,2 / 60,7 †</td><td>41.0</td><td>39.3</td><td>50.8</td><td>59.3</td><td>54.2</td><td>54.0</td></tr><tr><td>Terminal-Bench 2.0 (Claude Code)</td><td>56,2 / 61,1 †</td><td>32.8</td><td>46.4</td><td>-</td><td>57.9</td><td>-</td><td>-</td></tr><tr><td>CyberGym</td><td>43.2</td><td>23.5</td><td>17.3</td><td>41.3</td><td>50.6</td><td>39.9</td><td>-</td></tr><tr><td>BrowseComp</td><td>62.0</td><td>52.0</td><td>51.4</td><td>60.6</td><td>37.0</td><td>37.8</td><td>-</td></tr><tr><td>BrowseComp (avec gestion du contexte)</td><td>75.9</td><td>67.5</td><td>67.6</td><td>74.9</td><td>67.8</td><td>59.2</td><td>65.8</td></tr><tr><td>BrowseComp-Zh</td><td>72.7</td><td>66.6</td><td>65.0</td><td>62.3</td><td>62.4</td><td>66.8</td><td>76.1</td></tr><tr><td>τ²-Bench</td><td>89.7</td><td>87.4</td><td>85.3</td><td>80.2</td><td>91.6</td><td>90.7</td><td>85.5</td></tr><tr><td>MCP-Atlas (ensemble public)</td><td>67.8</td><td>52.0</td><td>62.2</td><td>63.8</td><td>65.2</td><td>66.6</td><td>68.0</td></tr><tr><td>Tool-Decathlon</td><td>38.0</td><td>23.8</td><td>35.2</td><td>27.8</td><td>43.5</td><td>36.4</td><td>46.3</td></tr><tr><td>Vending Bench 2</td><td>$4,432.12</td><td>$2,376.82</td><td>$1,034.00</td><td>$1,198.46</td><td>$4,967.06</td><td>$5,478.16</td><td>$3,591.33</td></tr></tbody></table>


---

# Agent Instructions: 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:

```
GET https://unsloth.ai/docs/fr/modeles/tutorials/glm-5.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
