# Guide de déploiement et d'inférence SGLang

Vous pouvez servir n'importe quel LLM ou modèle affiné via [SGLang](https://github.com/sgl-project/sglang) pour une inférence à faible latence et à haut débit. SGLang prend en charge l'inférence de modèles texte, image/vidéo sur n'importe quelle configuration GPU, avec prise en charge de certains GGUF.

### :computer:Installation de SGLang

Pour installer SGLang et Unsloth sur des GPU NVIDIA, vous pouvez utiliser ce qui suit dans un environnement virtuel (ce qui n'affectera pas vos autres bibliothèques Python)

```shellscript
# OPTIONNEL : utilisez un environnement virtuel
python -m venv unsloth_env
source unsloth_env/bin/activate

# Installez Rust, outlines-core puis SGLang
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env && sudo apt-get install -y pkg-config libssl-dev
pip install --upgrade pip && pip install uv
uv pip install "sglang" && uv pip install unsloth
```

Pour **Docker** configurations exécutées :

{% code overflow="wrap" %}

```shellscript
docker run --gpus all \
    --shm-size 32g \
    -p 30000:30000 \
    -v ~/.cache/huggingface:/root/.cache/huggingface \
    --env "HF_TOKEN=<secret>" \
    --ipc=host \
    lmsysorg/sglang:latest \
    python3 -m sglang.launch_server --model-path unsloth/Llama-3.1-8B-Instruct --host 0.0.0.0 --port 30000
```

{% endcode %}

### :bug:Débogage des problèmes d'installation de SGLang

Note : si vous voyez ce qui suit, mettez à jour Rust et outlines-core comme indiqué dans [#setting-up-sglang](#setting-up-sglang "mention")

{% code overflow="wrap" %}

```
indice : Cela indique généralement un problème avec le paquet ou l'environnement de compilation.
  aide : `outlines-core` (v0.1.26) a été inclus parce que `sglang` (v0.5.5.post2) dépend de `outlines` (v0.1.11) qui dépend de `outlines-core`
```

{% endcode %}

Si vous voyez un problème Flashinfer comme ci-dessous :

```
/home/daniel/.cache/flashinfer/0.5.2/100a/generated/batch_prefill_with_kv_cache_dtype_q_bf16_dtype_kv_bf16_dtype_o_bf16_dtype_idx_i32_head_dim_qk_64_head_dim_vo_64_posenc_0_use_swa_False_use_logits_cap_False_f16qk_False/batch_prefill_ragged_kernel_mask_1.cu:1:10: fatal error: flashinfer/attention/prefill.cuh: No such file or directory
    1 | #include <flashinfer/attention/prefill.cuh>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminée.
ninja : build stopped : commande secondaire échouée.

Solutions possibles :
1. définir --mem-fraction-static sur une valeur plus petite (par exemple, 0.8 ou 0.7)
2. définir --cuda-graph-max-bs sur une valeur plus petite (par exemple, 16)
3. désactiver la compilation torch en n'utilisant pas --enable-torch-compile
4. désactiver CUDA graph avec --disable-cuda-graph. (Non recommandé. Perte de performance importante)
Ouvrez une issue sur GitHub https://github.com/sgl-project/sglang/issues/new/choose
```

Supprimez le cache flashinfer via `rm -rf .cache/flashinfer` et aussi le répertoire indiqué dans le message d'erreur, par ex. `rm -rf ~/.cache/flashinfer`

### :truck:Déploiement des modèles SGLang

Pour déployer n'importe quel modèle comme par exemple [unsloth/Llama-3.2-1B-Instruct](https://huggingface.co/unsloth/Llama-3.2-1B-Instruct), faites ce qui suit dans un terminal séparé (sinon cela bloquera votre terminal actuel - vous pouvez aussi utiliser tmux) :

{% code overflow="wrap" %}

```shellscript
python3 -m sglang.launch_server \
    --model-path unsloth/Llama-3.2-1B-Instruct \
    --host 0.0.0.0 --port 30000
```

{% endcode %}

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fq3rBt5dn2PhrpvvfhSzo%2Fimage.png?alt=media&#x26;token=e7a5170b-eabb-4a11-ae4b-f27a11213ae3" alt=""><figcaption></figcaption></figure>

Vous pouvez ensuite utiliser la bibliothèque OpenAI Chat completions pour appeler le modèle (dans un autre terminal ou en utilisant tmux) :

```python
# Installez openai via pip install openai
from openai import OpenAI
import json
openai_client = OpenAI(
    base_url = "http://0.0.0.0:30000/v1",
    api_key = "sk-no-key-required",
)
completion = openai_client.chat.completions.create(
    model = "unsloth/Llama-3.2-1B-Instruct",
    messages = [{"role": "user", "content": "What is 2+2?"},],
)
print(completion.choices[0].message.content)
```

Et vous obtiendrez `2 + 2 = 4.`

### 🦥Déploiement des finetunes Unsloth dans SGLang

Après le fine-tuning [fine-tuning-llms-guide](https://unsloth.ai/docs/fr/commencer/fine-tuning-llms-guide "mention") ou en utilisant nos notebooks à [unsloth-notebooks](https://unsloth.ai/docs/fr/commencer/unsloth-notebooks "mention"), vous pouvez sauvegarder ou déployer vos modèles directement via SGLang dans un flux de travail unique. Un exemple de script de finetuning Unsloth par ex. :

```python
from unsloth import FastLanguageModel
import torch
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = "unsloth/gpt-oss-20b",
    max_seq_length = 2048,
    load_in_4bit = True,
)
model = FastLanguageModel.get_peft_model(model)
```

**Pour sauvegarder en 16 bits pour SGLang, utilisez :**

```python
model.save_pretrained_merged("finetuned_model", tokenizer, save_method = "merged_16bit")
## OU pour téléverser sur HuggingFace :
model.push_to_hub_merged("hf/model", tokenizer, save_method = "merged_16bit", token = "")
```

**Pour sauvegarder seulement les adaptateurs LoRA**, utilisez soit :

```python
model.save_pretrained("finetuned_model")
tokenizer.save_pretrained("finetuned_model")
```

Ou utilisez simplement notre fonction intégrée pour le faire :

```python
model.save_pretrained_merged("model", tokenizer, save_method = "lora")
## OU pour téléverser sur HuggingFace
model.push_to_hub_merged("hf/model", tokenizer, save_method = "lora", token = "")
```

### :railway\_car:gpt-oss-20b : Guide de déploiement Unsloth & SGLang

Ci-dessous un tutoriel étape par étape avec des instructions pour entraîner le [gpt-oss](https://unsloth.ai/docs/fr/modeles/gpt-oss-how-to-run-and-fine-tune)-20b en utilisant Unsloth et le déployer avec SGLang. Il inclut des benchmarks de performance pour plusieurs formats de quantification.

{% stepper %}
{% step %}

#### Finetuning Unsloth et formats d'exportation

Si vous débutez en fine-tuning, vous pouvez lire notre [guide](https://unsloth.ai/docs/fr/commencer/fine-tuning-llms-guide), ou essayer le notebook de finetuning gpt-oss 20B à [gpt-oss-how-to-run-and-fine-tune](https://unsloth.ai/docs/fr/modeles/gpt-oss-how-to-run-and-fine-tune "mention") Après l'entraînement, vous pouvez exporter le modèle dans plusieurs formats :

{% code overflow="wrap" %}

```python
model.save_pretrained_merged(
    "finetuned_model", 
    tokenizer, 
    save_method = "merged_16bit",
)
## Pour les conversions mxfp4 spécifiques à gpt-oss :
model.save_pretrained_merged(
    "finetuned_model", 
    tokenizer, 
    save_method = "mxfp4", # (UNIQUEMENT POUR gpt-oss sinon choisissez "merged_16bit")
)
```

{% endcode %}
{% endstep %}

{% step %}

#### Déploiement avec SGLang

Nous avons sauvegardé notre finetune gpt-oss dans le dossier "finetuned\_model", et donc dans un nouveau terminal, nous pouvons lancer le modèle finetuné comme point de terminaison d'inférence avec SGLang :

```shellscript
python -m sglang.launch_server \
    --model-path finetuned_model \
    --host 0.0.0.0 --port 30002
```

Vous pourriez devoir attendre un peu sur `Capturing batches (bs=1 avail_mem=20.84 GB) :` !
{% endstep %}

{% step %}

#### Appel du point de terminaison d'inférence :

Pour appeler le point de terminaison d'inférence, lancez d'abord un nouveau terminal. Nous pouvons alors appeler le modèle comme ci-dessous :

{% code overflow="wrap" %}

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

## SORTIE ##
# <|channel|>analysis<|message|>L'utilisateur pose une simple question de mathématiques. Nous devrions répondre 4. De plus, nous devons respecter la politique. Aucun problème.<|end|><|start|>assistant<|channel|>final<|message|>2 + 2 égale 4.
```

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

### :gem:Quantification FP8 en ligne

Pour déployer des modèles avec quantification FP8 en ligne qui permet 30 à 50 % de débit en plus et 50 % de mémoire en moins avec un support de contexte deux fois plus long dans SGLang, vous pouvez faire ce qui suit :

{% code overflow="wrap" %}

```shellscript
python -m sglang.launch_server \
    --model-path unsloth/Llama-3.2-1B-Instruct \
    --host 0.0.0.0 --port 30002 \
    --quantization fp8 \
    --kv-cache-dtype fp8_e4m3
```

{% endcode %}

Vous pouvez également utiliser `--kv-cache-dtype fp8_e5m2` qui a une plage dynamique plus grande qui pourrait résoudre des problèmes d'inférence FP8 si vous en rencontrez. Ou utilisez nos quants float8 pré-quantifiés listés dans <https://huggingface.co/unsloth/models?search=-fp8> ou certains sont listés ci-dessous :

{% embed url="<https://huggingface.co/unsloth/Llama-3.2-3B-FP8-Dynamic>" %}

{% embed url="<https://huggingface.co/unsloth/Llama-3.3-70B-Instruct-FP8-Dynamic>" %}

### ⚡Benchmarking SGLang

Voici du code que vous pouvez exécuter pour tester la vitesse de performance de votre modèle finetuné :

```shellscript
python -m sglang.launch_server \
    --model-path finetuned_model \
    --host 0.0.0.0 --port 30002
```

Puis dans un autre terminal ou via tmux :

```shellscript
# Taille de lot=8, Entrée=1024, Sortie=1024
python -m sglang.bench_one_batch_server \
    --model finetuned_model \
    --base-url http://0.0.0.0:30002 \
    --batch-size 8 \
    --input-len 1024 \
    --output-len 1024
```

Vous verrez le benchmark s'exécuter comme ci-dessous :

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FhcGy7cwC2xFaPA7FcJJq%2Fimage.png?alt=media&#x26;token=05687013-8af5-4731-8dae-b8cc05d44f21" alt=""><figcaption></figcaption></figure>

Nous avons utilisé un GPU B200x1 avec gpt-oss-20b et obtenu les résultats ci-dessous (\~2 500 tokens de débit)

| Batch/Entrée/Sortie | TTFT (s) | ITL (s) | Débit d'entrée | Débit de sortie |
| ------------------- | -------- | ------- | -------------- | --------------- |
| 8/1024/1024         | 0.40     | 3.59    | 20,718.95      | 2,562.87        |
| 8/8192/1024         | 0.42     | 3.74    | 154,459.01     | 2,473.84        |

Voir <https://docs.sglang.ai/advanced_features/server_arguments.html> pour les arguments du serveur pour SGLang.

### :person\_running:Mode interactif hors ligne SGLang

Vous pouvez aussi utiliser SGLang en mode hors ligne (c.-à-d. pas un serveur) dans un environnement interactif Python.

{% code overflow="wrap" %}

```python
import sglang as sgl
engine = sgl.Engine(model_path = "unsloth/Qwen3-0.6B", random_seed = 42)

prompt = "Aujourd'hui il fait beau et j'aime"
sampling_params = {"temperature": 0, "max_new_tokens": 256}
outputs = engine.generate(prompt, sampling_params)["text"]
print(outputs)
engine.shutdown()
```

{% endcode %}

### :sparkler:GGUFs dans SGLang

SGLang prend aussi, de manière intéressante, en charge les GGUF ! **Qwen3 MoE est encore en construction, mais la plupart des modèles denses (Llama 3, Qwen 3, Mistral, etc.) sont pris en charge.**

Installez d'abord le dernier paquet gguf python via :

{% code overflow="wrap" %}

```shellscript
pip install -e "git+https://github.com/ggml-org/llama.cpp.git#egg=gguf&subdirectory=gguf-py" # installer un paquet python depuis un sous-répertoire d'un dépôt
```

{% endcode %}

Ensuite, par exemple en mode hors ligne SGLang, vous pouvez faire :

{% code overflow="wrap" %}

```python
from huggingface_hub import hf_hub_download
model_path = hf_hub_download(
    "unsloth/Qwen3-32B-GGUF",
    filename = "Qwen3-32B-UD-Q4_K_XL.gguf",
)
import sglang as sgl
engine = sgl.Engine(model_path = model_path, random_seed = 42)

prompt = "Aujourd'hui il fait beau et j'aime"
sampling_params = {"temperature": 0, "max_new_tokens": 256}
outputs = engine.generate(prompt, sampling_params)["text"]
print(outputs)
engine.shutdown()
```

{% endcode %}

### :clapper:Service GGUF à haut débit avec SGLang

Téléchargez d'abord le fichier GGUF spécifique comme ci-dessous :

{% code overflow="wrap" %}

```python
from huggingface_hub import hf_hub_download
hf_hub_download("unsloth/Qwen3-32B-GGUF", filename="Qwen3-32B-UD-Q4_K_XL.gguf", local_dir=".")
```

{% endcode %}

Puis servez le fichier spécifique `Qwen3-32B-UD-Q4_K_XL.gguf` et utilisez `--served-model-name unsloth/Qwen3-32B` et nous avons aussi besoin du tokenizer compatible HuggingFace via `--tokenizer-path`

```shellscript
python -m sglang.launch_server \
    --model-path Qwen3-32B-UD-Q4_K_XL.gguf \
    --host 0.0.0.0 --port 30002 \
    --served-model-name unsloth/Qwen3-32B \
    --tokenizer-path unsloth/Qwen3-32B
```
