Aller au contenu

« Trace install tas - SGLang » : différence entre les versions

De Loic Wiki
Daneel (discussion | contributions)
Documenter le déploiement SGLang ROCm et le blocage gfx1100
 
Ajout du commit local de déploiement SGLang
 
(Une version intermédiaire par le même utilisateur non affichée)
Ligne 1 : Ligne 1 :
{{Projet|SGLang}}
{{Projet|SGLang}}
== SGLang ROCm — déploiement préparé ==
== SGLang ROCm — Qwen3.8 27B W8A8 déployé ==


{{Encadré|couleur=orange|titre=État au 18 août 2026|contenu=Le Quadlet, l'image et le modèle sont installés, mais le service est arrêté : l'image SGLang ROCm testée ne fournit pas les kernels PyTorch nécessaires à la Radeon RX 7900 XTX (gfx1100).}}
{{Encadré|couleur=vert|titre=État au 20 août 2026|contenu=Le service SGLang est actif sur la Radeon RX 7900 XTX. Qwen3.8 27B W8A8 répond sur l'API OpenAI locale avec un contexte de 32 768 tokens. Le test déterministe 17 + 25 renvoie 42 avant et après redémarrage.}}


=== Composants ===
=== Composants ===
* Unité Quadlet rootless : <code>sglang.service</code>, activée pour <code>default.target</code>
* Quadlet : <code>/home/loic/.config/containers/systemd/sglang.container</code>
* Quadlet : <code>/home/loic/.config/containers/systemd/sglang.container</code>
* Unité : <code>sglang.service</code>
* Conteneur : <code>sglang-qwen38-w8a8</code>
* Image : <code>docker.io/lmsysorg/sglang:v0.5.17-rocm700-mi30x</code>
* Image : <code>localhost/sglang:qwen38-w8a8-rdna3-21c88f8</code>
* Modèle : <code>Qwen/Qwen2.5-Coder-32B-Instruct-AWQ</code>
* Image ID : <code>06977e11fa96592e779eba01f41229884553d490788b3c73ad80aec6edeb05d3</code>
* Poids : <code>/media/loic/nem/sglang/models/Qwen2.5-Coder-32B-Instruct-AWQ</code>
* API : <code>http://127.0.0.1:30000/v1</code>, non publiée sur le LAN
* Taille des cinq safetensors : environ 19 Gio binaires, soit un peu plus de 20 Go décimaux
* Nom OpenAI : <code>qwen3.8-27b-w8a8</code>
* Port prévu : <code>127.0.0.1:30000</code>
* Checkpoint : <code>Freaksterz/Qwen3.8-27B-SmoothQuant-W8A8-INT8</code>, révision <code>68746dd</code>
* Volume conteneur : <code>/models</code>
* Quantification : poids INT8 par canal et activations INT8 dynamiques par token (<code>compressed-tensors</code>, W8A8)
* GPU ciblé : Radeon RX 7900 XTX, 24 Gio, <code>gfx1100</code>
* GPU : Radeon RX 7900 XTX 24 Gio, architecture <code>gfx1100</code>


=== Procédure appliquée ===
=== Profil retenu ===
# Vérification de Podman rootless, de la VRAM et de l'espace disponible.
# Création du répertoire persistant <code>/media/loic/nem/sglang</code>.
# Import de l'image ROCm SGLang et création du Quadlet.
# Téléchargement vérifiable du dépôt public Qwen avec reprise automatique.
# Test d'accès aux périphériques AMD : SGLang voit bien la Radeon RX 7900 XTX.
# Test de chargement réel du modèle.
 
=== Blocage identifié ===
Le test minimal suivant échoue dans l'image actuelle :
<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
torch.ones(1, device="cuda")
--context-length 32768
HIP error: invalid device function
--cpu-offload-gb 14
--mem-fraction-static 0.80
--max-running-requests 1
--chunked-prefill-size 2048
--attention-backend triton
--sampling-backend pytorch
--cuda-graph-backend-decode disabled
--cuda-graph-backend-prefill disabled
</syntaxhighlight>
</syntaxhighlight>


L'image <code>mi30x</code> détecte le GPU mais sa pile PyTorch/ROCm est compilée pour la famille Instinct. Les tentatives <code>HSA_OVERRIDE_GFX_VERSION=10.3.0</code> et <code>11.0.0</code> n'ont pas rendu le service fonctionnel : AITER refuse <code>gfx1030</code>, tandis que <code>gfx1100</code> reproduit l'erreur HIP. Le problème est donc une incompatibilité de kernels, pas un manque de VRAM ni un fichier de modèle incomplet.
Le modèle accepte nativement 262 144 tokens, mais le profil 256K n'est pas réaliste sur cette carte avec des poids 8 bits. Après chargement, <code>rocm-smi</code> mesure environ 22,5 Go de VRAM utilisés sur 25,75 Go décimaux. Le démarrage à froid dure environ 80 à 90 secondes. Le premier appel après redémarrage compile encore des noyaux Triton et a pris 63,7 secondes lors du contrôle final ; le même test à chaud prend environ 18 secondes.
 
Ollama peut rester actif sans modèle chargé. Il ne faut toutefois pas charger simultanément un gros modèle Ollama, faute de marge VRAM ; arrêter SGLang ou décharger Ollama au préalable.
 
=== Construction RDNA3 et correctif ===
Le dépôt de travail est <code>/media/loic/nem/sglang/build-rdna3/sglang-qwen38-current</code>, branche <code>deploy/qwen38-rdna3</code>, base SGLang <code>21c88f862</code>, déploiement figé au commit local <code>19d7dd612</code>. L'image de base immuable est <code>localhost/sglang:qwen38-rdna3-21c88f8-base</code>. La couche finale se trouve dans <code>docker/rdna3-w8a8-runtime.Dockerfile</code>.


Le service est laissé arrêté pour éviter un redémarrage en boucle. Il pourra reprendre avec une image SGLang/PyTorch compilée pour <code>gfx1100</code>, ou avec une image dédiée construite depuis une base ROCm Radeon. Le modèle et le Quadlet ne doivent pas être supprimés.
Le correctif déterminant concerne le déport CPU. SGLang exécute les couches déportées avec <code>torch.func.functional_call</code>. La vue <code>attn.conv_weights</code>, créée pendant l'initialisation, restait attachée à l'ancien stockage au lieu du poids <code>conv1d.weight</code> substitué. Cette vue est maintenant rafraîchie dans le passage avant. Le test W8A8 est alors passé de sorties invalides à une génération exacte.


=== Contrôles et reprise ===
Un port du GGUF Q8_0 officiel a aussi été chargé. Les multiplications et le remappage des poids sont numériquement corrects, mais la génération finale échoue encore au contrôle sémantique. Cette variante n'est pas déployée et reste étiquetée <code>localhost/sglang:qwen38-rdna3-21c88f8-gguf-experimental</code> pour diagnostic.
 
=== Contrôles ===
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
systemctl --user status sglang.service --no-pager
systemctl --user status sglang.service --no-pager
journalctl --user -u sglang.service -f
podman logs -f sglang-qwen38-w8a8
curl -fsS http://127.0.0.1:30000/v1/models
curl -fsS http://127.0.0.1:30000/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{
    "model":"qwen3.8-27b-w8a8",
    "messages":[{"role":"user","content":"Réponds uniquement par le nombre exact : 17 + 25 = ?"}],
    "temperature":0,
    "max_tokens":8,
    "chat_template_kwargs":{"enable_thinking":false}
  }'
</syntaxhighlight>
Résultat attendu et observé : <code>42</code>, arrêt sur le token de fin, 30 tokens d'entrée et 3 tokens de sortie. L'inventaire renvoie <code>max_model_len: 32768</code>. La génération texte est validée ; la partie vision présente dans le checkpoint ne l'est pas encore.
=== Exploitation et retour arrière ===
<syntaxhighlight lang="bash">
systemctl --user start sglang.service
systemctl --user start sglang.service
curl -fsS http://127.0.0.1:30000/health
systemctl --user stop sglang.service
podman logs sglang
systemctl --user restart sglang.service
</syntaxhighlight>
 
La sauvegarde antérieure se trouve dans <code>/home/loic/backups/sglang-qwen38-20260820T084200+0200/</code>. Pour arrêter sans supprimer les images, checkpoints ou caches :
 
<syntaxhighlight lang="bash">
systemctl --user disable --now sglang.service
</syntaxhighlight>
</syntaxhighlight>


=== Sauvegardes ===
La documentation détaillée est dans <code>/home/loic/mediawiki/docs/sglang.md</code>. Les artefacts ont aussi été copiés dans Nextcloud sous <code>minidev/sglang-qwen38-w8a8/</code>.
* Déploiement : <code>/home/loic/backups/sglang-20260818T204121+0200/</code>
* Quadlet avant le dernier test GPU : <code>sglang.container.before-gfx-override</code>
* Sauvegardes des pages MediaWiki avant publication : sous-répertoire <code>wiki/</code> du dossier ci-dessus


=== Références ===
=== Références ===
* [https://github.com/sgl-project/sglang/blob/main/docs/platforms/amd_gpu.md SGLang — AMD GPU]
* [https://docs.sglang.io/docs/advanced_features/server_arguments.html SGLang — arguments serveur]
* [https://github.com/sgl-project/sglang/issues/30599 Suivi officiel de l'activation Radeon RDNA3/RDNA4]
* [https://docs.sglang.io/docs/advanced_features/quantization.html SGLang — quantification]
* [https://huggingface.co/Qwen/Qwen2.5-Coder-32B-Instruct-AWQ Qwen2.5-Coder-32B-Instruct-AWQ]
* [https://huggingface.co/Qwen/Qwen3.8-27B Qwen3.8-27B officiel]
* [https://huggingface.co/Freaksterz/Qwen3.8-27B-SmoothQuant-W8A8-INT8 Checkpoint W8A8 utilisé]
* [https://github.com/ggml-org/llama.cpp/blob/master/conversion/qwen.py Conversion Qwen dans llama.cpp]

Dernière version du 20 août 2026 à 14:27

Modèle:Projet

SGLang ROCm — Qwen3.8 27B W8A8 déployé

Modèle:Encadré

Composants

  • Unité Quadlet rootless : sglang.service, activée pour default.target
  • Quadlet : /home/loic/.config/containers/systemd/sglang.container
  • Conteneur : sglang-qwen38-w8a8
  • Image : localhost/sglang:qwen38-w8a8-rdna3-21c88f8
  • Image ID : 06977e11fa96592e779eba01f41229884553d490788b3c73ad80aec6edeb05d3
  • API : http://127.0.0.1:30000/v1, non publiée sur le LAN
  • Nom OpenAI : qwen3.8-27b-w8a8
  • Checkpoint : Freaksterz/Qwen3.8-27B-SmoothQuant-W8A8-INT8, révision 68746dd
  • Quantification : poids INT8 par canal et activations INT8 dynamiques par token (compressed-tensors, W8A8)
  • GPU : Radeon RX 7900 XTX 24 Gio, architecture gfx1100

Profil retenu

--context-length 32768
--cpu-offload-gb 14
--mem-fraction-static 0.80
--max-running-requests 1
--chunked-prefill-size 2048
--attention-backend triton
--sampling-backend pytorch
--cuda-graph-backend-decode disabled
--cuda-graph-backend-prefill disabled

Le modèle accepte nativement 262 144 tokens, mais le profil 256K n'est pas réaliste sur cette carte avec des poids 8 bits. Après chargement, rocm-smi mesure environ 22,5 Go de VRAM utilisés sur 25,75 Go décimaux. Le démarrage à froid dure environ 80 à 90 secondes. Le premier appel après redémarrage compile encore des noyaux Triton et a pris 63,7 secondes lors du contrôle final ; le même test à chaud prend environ 18 secondes.

Ollama peut rester actif sans modèle chargé. Il ne faut toutefois pas charger simultanément un gros modèle Ollama, faute de marge VRAM ; arrêter SGLang ou décharger Ollama au préalable.

Construction RDNA3 et correctif

Le dépôt de travail est /media/loic/nem/sglang/build-rdna3/sglang-qwen38-current, branche deploy/qwen38-rdna3, base SGLang 21c88f862, déploiement figé au commit local 19d7dd612. L'image de base immuable est localhost/sglang:qwen38-rdna3-21c88f8-base. La couche finale se trouve dans docker/rdna3-w8a8-runtime.Dockerfile.

Le correctif déterminant concerne le déport CPU. SGLang exécute les couches déportées avec torch.func.functional_call. La vue attn.conv_weights, créée pendant l'initialisation, restait attachée à l'ancien stockage au lieu du poids conv1d.weight substitué. Cette vue est maintenant rafraîchie dans le passage avant. Le test W8A8 est alors passé de sorties invalides à une génération exacte.

Un port du GGUF Q8_0 officiel a aussi été chargé. Les multiplications et le remappage des poids sont numériquement corrects, mais la génération finale échoue encore au contrôle sémantique. Cette variante n'est pas déployée et reste étiquetée localhost/sglang:qwen38-rdna3-21c88f8-gguf-experimental pour diagnostic.

Contrôles

systemctl --user status sglang.service --no-pager
journalctl --user -u sglang.service -f
podman logs -f sglang-qwen38-w8a8
curl -fsS http://127.0.0.1:30000/v1/models

curl -fsS http://127.0.0.1:30000/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{
    "model":"qwen3.8-27b-w8a8",
    "messages":[{"role":"user","content":"Réponds uniquement par le nombre exact : 17 + 25 = ?"}],
    "temperature":0,
    "max_tokens":8,
    "chat_template_kwargs":{"enable_thinking":false}
  }'

Résultat attendu et observé : 42, arrêt sur le token de fin, 30 tokens d'entrée et 3 tokens de sortie. L'inventaire renvoie max_model_len: 32768. La génération texte est validée ; la partie vision présente dans le checkpoint ne l'est pas encore.

Exploitation et retour arrière

systemctl --user start sglang.service
systemctl --user stop sglang.service
systemctl --user restart sglang.service

La sauvegarde antérieure se trouve dans /home/loic/backups/sglang-qwen38-20260820T084200+0200/. Pour arrêter sans supprimer les images, checkpoints ou caches :

systemctl --user disable --now sglang.service

La documentation détaillée est dans /home/loic/mediawiki/docs/sglang.md. Les artefacts ont aussi été copiés dans Nextcloud sous minidev/sglang-qwen38-w8a8/.

Références