Tu veux un agent de développement qui ne te dise pas « désolé, je ne peux pas t’aider » toutes les cinq minutes. Tu veux un modèle qui comprenne le code, qui appelle des outils, qui lise tes fichiers, qui exécute des commandes — sans se censurer. Et tu veux que ça tourne sur du matériel sérieux, pas sur ton MacBook qui chauffe comme un four.
La solution : louer un GPU sur Vast.ai, y installer un Qwen3 abliterated (un modèle non censuré qui garde intact son function calling), le servir en API OpenAI-compatible, puis y accéder depuis ton VS Code local via un tunnel VPS. Tout ça pour quelques dollars de l’heure, avec la possibilité de tout éteindre quand tu as fini.
Ce tutoriel est un guide technique de bout en bout. Chaque commande est testée, chaque étape est reproductible. On ne va pas te raconter que c’est révolutionnaire ou que tu vas passer de zéro à héros. On va te montrer comment ça marche, point.
Ce qu'il te faut
Avant de commencer, assure-toi d’avoir :
- Un compte Vast.ai (https://cloud.vast.ai/) avec au moins 5 $ de crédit (Stripe, BitPay ou Crypto.com). Le dépôt minimum est de 5 $, et c’est suffisant pour une nuit de travail.
- Un VPS (n’importe lequel : OVH, Hetzner, DigitalOcean, même un Raspberry Pi en colocation si tu es maso). Il sert de relais stable entre ton instance GPU éphémère et ta machine locale. Si tu n’en as pas, tu peux sauter cette étape et utiliser directement le port forwarding SSH de Vast.ai, mais c’est moins propre.
- VS Code installé sur ta machine locale, avec au moins une des extensions suivantes : Continue, Cline ou Roo Code.
- Des bases en SSH : savoir générer une clé, se connecter à une machine distante. Rien de sorcier, mais si tu ne sais pas ce que c’est, commence par là.
- Un terminal, du café, et un peu de patience. Les images Docker peuvent mettre du temps à se télécharger.
Étape 1 — Louer une instance GPU sur Vast.ai
Créer un compte et créditer son solde
- Va sur https://cloud.vast.ai/ et crée un compte. Vérifie ton adresse e-mail (obligatoire, sinon tu ne pourras pas louer de machine).
- Ajoute du crédit via Billing → Add Credit. Moyens de paiement acceptés : carte bancaire (Stripe), crypto (BitPay, Crypto.com). Minimum : 5 $.
Astuce : active l’autobilling si tu veux éviter de te retrouver à court de crédit en pleine session. Configure un seuil de recharge et une alerte e-mail pour être prévenu avant que ça ne coupe.
Trouver la bonne offre
Rends-toi sur https://cloud.vast.ai/create/. C’est là que tu vas filtrer les offres pour trouver la perle rare.
Filtres à appliquer (selon ton besoin) :
- Type de GPU : pour ce tutoriel, on va cibler soit une RTX 4090 24 Go (économique), soit une RTX A6000 48 Go (pour plus de marge).
- Mémoire GPU (VRAM) : 24 Go minimum pour notre exemple.
- Prix : entre 0,25 $/h et 0,50 $/h pour une RTX 4090, 0,30–0,50 $/h pour une A6000.
- Fiabilité (Reliability Score) : privilégie les machines avec un score > 80 %. Toutes les machines démarrent à 60 %, mais celles qui montent au-dessus ont fait leurs preuves.
- Type d’instance : on-demand pour une session critique (priorité maximale), interruptible pour économiser (jusqu’à -50 %, mais tu peux te faire déconnecter à tout moment).
Note : Vast.ai est un marché. Les prix fluctuent en temps réel. Une RTX 4090 peut coûter 0,29 $/h en interruptible ou 0,51 $/h en on-demand. Vérifie toujours le prix affiché avant de louer.
Lancer l’instance
Une fois que tu as trouvé une offre qui te convient, clique dessus. Voici les paramètres à configurer :
- Image Docker :
pytorch/pytorch:2.1.0-cuda11.8-cudnn8-runtime(ou une version plus récente si disponible). C’est une image officielle PyTorch avec CUDA préinstallé. - Mode de lancement : SSH only (on n’a pas besoin de Jupyter pour ce tutoriel).
- Taille du disque : 50 Go minimum (tu peux monter à 100 Go si tu prévois d’installer plusieurs modèles). Attention : cette taille est définitive. Si tu manques de place, il faudra recréer une instance avec un disque plus grand.
- On-start Script : laisse vide pour l’instant. On verra plus tard comment l’utiliser pour automatiser le démarrage de vLLM.
Piège : ne pas préciser de tag de version pour l’image Docker peut provoquer une erreur
server_errorau moment de louer. Toujours utiliser un tag explicite.
Une fois l’instance lancée, attends qu’elle passe en statut Connect. Ça peut prendre entre 2 et 5 minutes (plus long si c’est un pull à froid de l’image Docker).
Clés SSH et connexion
- Génère une paire de clés SSH si tu n’en as pas déjà une :
ssh-keygen -t ed25519 -C "ton_email@example.com"Cela crée deux fichiers dans ~/.ssh/ : id_ed25519 (clé privée, à ne jamais partager) et id_ed25519.pub (clé publique).
- Ajoute ta clé publique à ton compte Vast.ai :
- Affiche ta clé publique : cat ~/.ssh/id_ed25519.pub
- Copie son contenu et colle-le dans https://cloud.vast.ai/manage-keys/ (section SSH Keys → +New).
- Connecte-toi à l’instance :
- Sur la page de ton instance, clique sur l’icône SSH pour obtenir la commande de connexion. Elle ressemble à ça :
ssh -p 50983 root@154.64.230.50- -p 50983 : le port SSH externe (aléatoire, mappé sur le port 22 interne).
- root : l’utilisateur est toujours root sur Vast.ai.
- 154.64.230.50 : l’IP publique de l’instance (souvent partagée entre plusieurs machines).
Note : l’authentification par mot de passe est désactivée. Seules les clés SSH sont acceptées.
- Transfert de fichiers (si besoin) :
# Envoyer un fichier VERS l'instance
scp -P 50983 mon_fichier.txt root@154.64.230.50:/workspace/
# Récupérer un fichier DEPUIS l'instance
scp -P 50983 root@154.64.230.50:/workspace/mon_fichier.txt ./Note :
scputilise-P(majuscule) pour le port, contrairement àsshqui utilise-p(minuscule).
Cycle de vie de l’instance
- Stop (icône carré) : met l’instance en pause. Les données sont conservées, mais le stockage continue d’être facturé (le GPU est libéré).
- Destroy (icône corbeille) : suppression définitive de l’instance et de toutes ses données. C’est la seule façon d’arrêter complètement la facturation.
- Restart (icône play) : tente de relancer l’instance si elle est arrêtée.
Règle d’or : une instance visible dans ton compte n’est jamais gratuite, même arrêtée. Le stockage est facturé en continu. Détruis les instances inutiles.
Exemple de coût
Voici ce que ça coûte pour une nuit de travail (10 heures) sur une RTX 4090 :
- Location GPU : 10 h × ~0,35 $/h ≈ 3,50 $
- Stockage : 10 h × ~0,10 $/Go/h (pour un disque de 50 Go) ≈ 0,05 $
- Bande passante : quelques Go téléchargés ≈ négligeable (quelques centimes)
Total estimé : 4 à 6 $ pour une session de 10 heures.
À retenir : le stockage est facturé même quand l’instance est arrêtée. Si tu laisses traîner une instance avec un disque de 200 Go pendant une semaine, ça peut coûter plus cher que la location du GPU elle-même.
Étape 2 — Choisir le modèle non censuré
Abliterated vs Dolphin : la différence qui compte
Il existe trois familles de modèles « non censurés ». Pour un agent de développement, seul l’abliterated est vraiment adapté.
- Abliterated : on identifie dans l’espace d’activation du modèle une « direction de refus » (la tendance à dire « je ne peux pas t’aider »), puis on la projette hors des matrices de poids. Résultat : le modèle n’a plus ce réflexe, sans perdre ses autres capacités (comme le function calling). C’est une édition sans entraînement, donc rapide et peu coûteuse.
- Dolphin : le modèle est fine-tuné sur un jeu de données dont les refus ont été filtrés. Il « n’apprend jamais » à refuser. Problème : le fine-tune peut dégrader la qualité ou l’alignement du modèle, et le function calling est moins fiable.
- Hermes 3/4 (de Nous Research) : d’excellents modèles de chat, mais orientés conversation. Pour un usage agentique (tool use intensif), ils sont moins adaptés que Qwen3 abliterated.
Pourquoi Qwen3 abliterated ?
- Function calling natif et fiable : Qwen3 est entraîné pour appeler des outils. L’abliteration retire uniquement la direction de refus, sans toucher au tool-calling.
- Grand contexte : Qwen3 supporte jusqu’à 128k tokens. Hermes Agent exige ≥ 64 000 tokens pour fonctionner correctement.
- Licence permissive (Apache 2.0) et écosystème bien outillé (vLLM, Ollama, llama.cpp).
Tableau des tailles, VRAM et GPU recommandés
Voici les modèles abliterated disponibles, leur taille, et le GPU Vast.ai qui convient.
Règle de calcul de la mémoire des poids :
- FP16 / BF16 :
2 octets × paramètres→ 8B ≈ 16 Go, 14B ≈ 28 Go, 32B ≈ 64 Go, 70B ≈ 140 Go. - 4-bit (GGUF Q4_K_M, AWQ, GPTQ) :
≈ 0,5–0,55 octet × paramètres→ 8B ≈ 5 Go, 14B ≈ 9 Go, 32B ≈ 19 Go, 70B ≈ 40 Go.
Il faut ajouter le cache KV + les activations (environ 2 à 6 Go selon le contexte). Les valeurs « VRAM totale » ci-dessous incluent une marge réaliste pour ~64k de contexte.
Modèle abliterated | Params | Poids FP16 | Poids 4-bit | VRAM totale FP16 | VRAM totale 4-bit | GPU Vast.ai recommandé |
|---|---|---|---|---|---|---|
| 8B | ~16 Go | ~5 Go | ~18 Go | ~7 Go | RTX 4060 Ti 16GB (4-bit confortable, FP16 serré) · RTX 4090 24GB |
| 14B | ~28 Go | ~9 Go | ~30 Go | ~11 Go | RTX 4090 24GB (4-bit) · RTX A6000 48GB (FP16) |
| 27B | ~54 Go | ~17,5 Go | ~57 Go | ~20 Go | RTX 4090 24GB (4-bit) · RTX A6000 48GB (4-bit + grand contexte) · A100 80GB (FP16) |
| 32B | ~64 Go | ~19 Go | ~68 Go | ~21 Go | RTX A6000 48GB (4-bit + grand contexte) · 2× RTX 4090 (4-bit) · A100 80GB (FP16) |
| 70B | ~140 Go | ~40 Go | ~145 Go | ~44 Go | A100 80GB / H100 80GB (4-bit) · 2× RTX A6000 48GB (4-bit) · 2×/4× A100 (FP16) |
Repères de prix Vast.ai (indicatifs, très fluctuants) :
- RTX 4060 Ti 16GB ≈ 0,10–0,15 $/h
- RTX 3090 24GB ≈ 0,15–0,25 $/h
- RTX 4090 24GB ≈ 0,25–0,40 $/h
- RTX A6000 48GB ≈ 0,30–0,50 $/h
- A100 80GB ≈ 0,70–1,00 $/h
- H100 80GB ≈ 1,50–2,50 $/h
Recommandation pratique :
- Pour un agent de dev, Qwen3-32B-abliterated en 4-bit sur une RTX A6000 48GB est le meilleur rapport qualité/prix.
- Le Huihui-Qwen3.8-27B-abliterated en 4-bit sur RTX 4090 24GB est l’option la plus économique pour une capacité quasi équivalente.
Attention : un Qwen3-32B en BF16 pèse ~64 Go de poids. Il ne tient pas sur une seule RTX 4090 (24 Go) ni sur une RTX A6000 (48 Go) en FP16. Pour l’exemple bout-en-bout, on utilisera donc une quantification 4-bit (AWQ ou GPTQ), qui réduit la taille à ~19 Go.
Étape 3 — Servir le modèle en API OpenAI-compatible
Trois options s’offrent à toi, par ordre de préférence pour un agent de développement :
Option 1 — vLLM (recommandé)
vLLM est le choix pour un agent : débit élevé, continuous batching, et surtout, un support natif du tool calling avec les bons flags.
Installation (sur l’instance GPU Vast.ai) :
pip install vllmAuthentification HuggingFace (pour les modèles gated comme huihui-ai) :
huggingface-cli login
# Suis les instructions pour te connecter et accepter les conditions d'accès au modèle.
export HF_TOKEN=hf_xxxxxxxxServir le modèle (exemple avec Qwen3-32B-abliterated en 4-bit AWQ) :
vllm serve huihui-ai/Qwen3-32B-abliterated \
--host 0.0.0.0 \
--port 8000 \
--served-model-name qwen3-32b-abliterated \ # nom logique pour l'API
--max-model-len 65536 \
--gpu-memory-utilization 0.95 \
--tensor-parallel-size 1 \
--enable-auto-tool-choice \
--tool-call-parser hermes \
--quantization awq # pour un checkpoint AWQ/GPTQExplications des flags :
--host 0.0.0.0: écoute sur toutes les interfaces (nécessaire pour le tunnel).--port 8000: le port sur lequel l’API sera accessible.--served-model-name: le nom du modèle tel qu’il apparaîtra dans l’API. Doit correspondre à ce que tu utiliseras dans les configs VS Code.--max-model-len 65536: fixe le contexte à 64k (Hermes Agent exige ≥ 64k).--gpu-memory-utilization 0.95: utilise 95 % de la VRAM disponible.--tensor-parallel-size 1: utilise un seul GPU (mets à 2 si tu as deux GPUs).--enable-auto-tool-choice: requis pour que Hermes Agent puisse utilisertool_choice: "auto".--tool-call-parser hermes: requis pour que les appels d’outils Qwen soient reconnus. Sans ce flag, les tool calls ressortent en texte brut et ne sont pas interprétés.--quantization awq: pour un checkpoint AWQ. Utilise--quantization gptqpour GPTQ, ou--quantization ggufpour un GGUF.
Test rapide :
# Vérifier que le modèle est bien servi
curl http://localhost:8000/v1/models
# Doit retourner un JSON avec "id": "qwen3-32b-abliterated"
# Envoyer une requête de test
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"qwen3-32b-abliterated","messages":[{"role":"user","content":"Bonjour, qui es-tu ?"}]}'Note : si tu utilises un modèle non quantifié (FP16/BF16), assure-toi que ton GPU a assez de VRAM. Pour un Qwen3-32B en FP16, il te faut au moins 68 Go de VRAM (poids + cache KV).
Option 2 — Ollama (simple mais limité)
Ollama est idéal pour démarrer rapidement, mais il a quelques pièges.
Installation :
curl -fsSL https://ollama.com/install.sh | shTélécharger et servir le modèle :
# Télécharger le modèle (les abliterated sont dans la bibliothèque huihui_ai)
ollama pull huihui_ai/Qwen3.8-abliterated # le 27B en Q4_K_M
ollama pull huihui_ai/qwen3-abliterated # la série Qwen3 8B
# Servir avec un contexte suffisant (64k)
OLLAMA_CONTEXT_LENGTH=64000 ollama servePièges à éviter :
- Piège n°1 : sans
OLLAMA_CONTEXT_LENGTH=64000, Hermes Agent refuse de démarrer (il exige ≥ 64k de contexte). - Piège n°2 : on ne peut pas fixer le contexte via l’API
/v1/chat/completions. Il faut le régler côté serveur ou via un Modelfile :
echo -e 'FROM huihui_ai/Qwen3.8-abliterated\nPARAMETER num_ctx 64000' > Modelfile
ollama create qwen3.8-64k -f ModelfileAPI : accessible sur http://localhost:11434/v1.
Option 3 — llama.cpp (pour les puristes)
llama.cpp est une option légère, surtout utile si tu veux tourner sur du CPU ou de l’Apple Silicon. Mais pour un GPU datacenter, vLLM est bien plus performant.
Build :
cmake -B build && cmake --build build --config ReleaseServir :
./build/bin/llama-server \
--jinja -fa \
-c 64000 \
-ngl 99 \
-m models/Qwen3-32B-abliterated-Q4_K_M.gguf \
--port 8080 --host 0.0.0.0Flags importants :
--jinjaest obligatoire pour le tool calling. Sans lui, le serveur ignore le paramètretoolset Hermes ne verra que du JSON brut.-fa: active toutes les optimisations GPU.-c 64000: contexte à 64k.-ngl 99: utilise toutes les couches GPU.
API : accessible sur http://localhost:8080/v1.
Note : pour utiliser llama.cpp, il te faut un modèle au format GGUF. Tu peux en trouver sur HuggingFace (filtre
library=gguf). Q4_K_M est le meilleur compromis qualité/mémoire.
Étape 4 — Installer Hermes Agent (ou ton agent de dev)
Hermes Agent est un agent de développement open-source qui peut appeler des outils, lire des fichiers, exécuter des commandes, et bien plus. Il est conçu pour fonctionner avec n’importe quel endpoint OpenAI-compatible.
Installation
# Linux / macOS / WSL2
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bashUne fois installé, tu peux lancer le setup interactif :
hermes model
# → Choisir "Custom endpoint (self-hosted / VLLM / etc.)"
# → URL : http://localhost:8000/v1 (vLLM) — ou :11434/v1 (Ollama) — ou :8080/v1 (llama.cpp)
# → API key : laisser vide (serveur local)
# → Nom du modèle : celui chargé par le serveur (ex: qwen3-32b-abliterated)Configuration manuelle — ~/.hermes/config.yaml
Si tu préfères tout configurer à la main, édite le fichier ~/.hermes/config.yaml :
# ~/.hermes/config.yaml
model:
default: huihui-ai/Qwen3-32B-abliterated # nom exact servi par vLLM/Ollama
provider: custom # "custom" = endpoint OpenAI-compatible
base_url: http://localhost:8000/v1 # vLLM ; http://localhost:11434/v1 pour Ollama
context_length: 65536 # Hermes exige ≥ 64000 ; s'aligne sur --max-model-lenVariante Ollama :
model:
default: huihui_ai/Qwen3.8-abliterated
provider: custom
base_url: http://localhost:11434/v1
context_length: 65536Points importants :
provider: customcouvre vLLM, Ollama et llama.cpp (les aliasollama,vllm,llamacpppointent tous verscustom).- Si l’auto-détection du contexte échoue (proxy sans
/v1/models), fixecontext_lengthmanuellement. - Une fois configuré, tu peux basculer de modèle en session avec
/model custom:<nom>.
Vérification
hermes doctor # inspecte la config et vérifie que tout est bon
hermes chat # ouvre une session ; le modèle local doit répondre
# En session : /model custom → auto-détecte le modèle servi (s'il n'y en a qu'un)Note : si tu as installé Hermes Agent sur ta machine locale mais que le modèle tourne sur l’instance Vast.ai, il te faudra un tunnel pour y accéder (voir Étape 5).
Étape 5 — Le tunnel VPS
Pourquoi un tunnel ?
Ton instance Vast.ai est derrière un NAT/pare-feu : ses ports ne sont pas joignables directement depuis Internet. Or, vLLM écoute sur http://localhost:8000/v1 à l’intérieur de l’instance. Pour que ton VS Code local puisse lui parler, il faut faire transiter le trafic à travers une machine à adresse publique stable : ton VPS.
Deux approches existent :
- Tunnel inverse (
ssh -R,frp,cloudflared) : l’instance sort vers le VPS. - Port forwarding direct (
ssh -L) : ta machine locale sort vers l’instance.
On va combiner les deux : l’instance pousse le port 8000 vers le VPS (ssh -R), puis ta machine locale tire ce port vers elle (ssh -L).
Le principe du tunnel inverse SSH (ssh -R)
Commande de base (depuis l’instance Vast.ai) :
ssh -R 8000:localhost:8000 user@IP_DU_VPSLecture : « Quand tu es connecté sur le VPS, ouvre le port 8000 et renvoie tout ce qui y arrive vers localhost:8000 sur la machine qui lance la commande (c’est-à-dire l’instance Vast.ai). »
Résultat : sur le VPS, un service écoute sur 127.0.0.1:8000 et le relaie vers vLLM.
Les pièges classiques
Piège n°1 — Le port n’est joignable que depuis le VPS lui-même. Par défaut, OpenSSH lie le port redirigé sur l’interface loopback (127.0.0.1) du serveur, pas sur 0.0.0.0. Pour que IP_DU_VPS:8000 soit joignable depuis l’extérieur, il faut :
# Sur le VPS, dans /etc/ssh/sshd_config :
GatewayPorts yes # ou "clientspecified"
# puis :
sudo systemctl reload ssh # ou sshdAvec GatewayPorts yes, la commande devient :
ssh -R 0.0.0.0:8000:localhost:8000 user@IP_DU_VPSSécurité : lier sur
0.0.0.0expose le port à tout Internet. Si vLLM est servi sans clé API, n’importe qui peut l’utiliser. PrivilégieGatewayPorts no(défaut) + unssh -Ldepuis ta machine locale (voir section suivante), ou mets une clé API avec--api-keyde vLLM.
Piège n°2 — La connexion meurt au premier coup de vent. Sans options, SSH coupe le tunnel au moindre timeout réseau. Ajoute systématiquement :
ssh -R 8000:localhost:8000 \
-o ServerAliveInterval=30 \
-o ServerAliveCountMax=3 \
-o ExitOnForwardFailure=yes \
user@IP_DU_VPSServerAliveInterval=30: envoie un paquet de keepalive toutes les 30 secondes.ServerAliveCountMax=3: après 3 échecs (~90 secondes), considère la liaison morte et la ferme.ExitOnForwardFailure=yes: si le port ne peut pas être forwardé (déjà occupé, refus du serveur), la commande échoue immédiatement au lieu de rester connectée sans tunnel.
Piège n°3 — Le port est déjà pris sur le VPS. ExitOnForwardFailure=yes + le message remote port forwarding failed for listen port 8000 signifient qu’un autre processus (ou un ancien tunnel) occupe le port. Vérifie avec ss -ltnp | grep 8000 et tue/ferme l’ancien.
Piège n°4 — L’authentification de l’instance vers le VPS. L’instance doit pouvoir se connecter sans mot de passe au VPS. Génère une clé dédiée sur l’instance et ajoute sa partie publique au ~/.ssh/authorized_keys du VPS.
# Sur l'instance Vast.ai
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_vps -N ""
cat ~/.ssh/id_ed25519_vps.pub # à coller dans le ~/.ssh/authorized_keys du VPSVariante complète : ssh -R + autossh + systemd
Pour un tunnel persistant et auto-réparateur, utilise autossh (qui relance SSH quand la liaison tombe) et encapsule-le dans un service systemd.
Installation d’autossh (sur l’instance Vast.ai) :
sudo apt-get update && sudo apt-get install -y autosshService systemd (/etc/systemd/system/vllm-tunnel.service) :
[Unit]
Description=Tunnel inverse vLLM vers le VPS
After=network-online.target
Wants=network-online.target
[Service]
User=root
Environment=AUTOSSH_GATETIME=0
ExecStart=/usr/bin/autossh -M 0 -NT \
-o "ServerAliveInterval=30" \
-o "ServerAliveCountMax=3" \
-o "ExitOnForwardFailure=yes" \
-i /root/.ssh/id_ed25519_vps \
-R 8000:localhost:8000 user@IP_DU_VPS
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetDétails importants :
-M 0: désactive le port de monitoring d’autossh (souvent bloqué). autossh se fie alors au keepalive SSH.-N: ne pas ouvrir de shell distant (on ne fait que forwarder).-T: pas d’allocation de pseudo-terminal.AUTOSSH_GATETIME=0: relance immédiatement au premier échec, sans période de grâce.
Activation :
sudo systemctl daemon-reload
sudo systemctl enable --now vllm-tunnel.service
systemctl status vllm-tunnel.service # doit afficher "active (running)"Note : tu peux te passer d’
autossh.Restart=alwaysde systemd suffit dans la plupart des cas. La commande devient alorsExecStart=/usr/bin/ssh -NT -o ... -R 8000:localhost:8000 user@IP_DU_VPS.autosshajoute de la valeur quand le réseau est instable.
Alternative 1 : frp (fast reverse proxy)
frp est un reverse proxy dédié, écrit en Go, qui fait exactement ce métier : exposer un service derrière NAT, avec plus de contrôle (auth par token, chiffrement, health-check, dashboard).
Sur le VPS — frps (serveur)
# Télécharger la dernière release (adapter l'architecture)
wget https://github.com/fatedier/frp/releases/download/v0.61.1/frp_0.61.1_linux_amd64.tar.gz
tar xzf frp_0.61.1_linux_amd64.tar.gz
cd frp_0.61.1_linux_amd64frps.toml :
bindPort = 7000 # port sur lequel frpc se connecte
# Sécurité recommandée : authentifier le client
auth.method = "token"
auth.token = "UN_TOKEN_ALEATOIRE_LONG"./frps -c ./frps.tomlNote : ouvre le port
7000dans le pare-feu du VPS (et, siremotePortest exposé publiquement, ce port aussi).
Sur l’instance Vast.ai — frpc (client)
Même archive téléchargée sur l’instance, puis frpc.toml :
serverAddr = "IP_DU_VPS"
serverPort = 7000
auth.method = "token"
auth.token = "UN_TOKEN_ALEATOIRE_LONG"
[[proxies]]
name = "vllm"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8000 # vLLM sur l'instance
remotePort = 8000 # exposé sur le VPS (0.0.0.0)./frpc -c ./frpc.tomlLecture : tout ce qui arrive sur IP_DU_VPS:8000 est relayé vers 127.0.0.1:8000 de l’instance. Contrairement à ssh -R, frps écoute par défaut sur 0.0.0.0 (accessible publiquement) — donc mets une clé API vLLM ou restreins le port avec le pare-feu du VPS.
frp en systemd (optionnel)
Crée un service systemd analogue à celui de la section précédente, avec ExecStart=/chemin/frpc -c /chemin/frpc.toml et Restart=always.
Alternative 2 : Cloudflare Tunnel
Cloudflare Tunnel (cloudflared) expose un service local via le réseau Cloudflare, sans ouvrir de port sur le VPS. Le binaire sort vers Cloudflare, qui fait proxy inverse.
Tunnel « TryCloudflare » (sans compte, usage ponctuel)
# Sur l'instance Vast.ai
cloudflared tunnel --url http://localhost:8000Cloudflare affiche alors une URL publique https://xxxx.trycloudflare.com qui pointe vers vLLM. Limites : URL aléatoire à chaque lancement, latence ajoutée, et HTTPS imposé (tes clients doivent parler en https).
Tunnel nommé (domaine persistant)
# Une seule fois, sur une machine qui a un navigateur :
cloudflared tunnel login # ouvre un lien, on choisit le domaine
cloudflared tunnel create vllm # génère un fichier .json de credentials
cloudflared tunnel route dns vllm vllm.example.com # crée le CNAME
# Sur l'instance Vast.ai, ~/.cloudflared/config.yml :
tunnel: <ID_DU_TUNNEL>
credentials-file: /root/.cloudflared/<ID>.json
ingress:
- hostname: vllm.example.com
service: http://localhost:8000
- service: http_status:404 # règle de repli obligatoirecloudflared tunnel run vllmLe client VS Code pointe alors vers https://vllm.example.com/v1. Attention : Cloudflare applique des limites de taille de corps de requête et de durée sur le plan gratuit, ce qui peut gêner les gros contextes ou les longs streams d’un agent de code. Pour un usage agentique (Cline/Roo), préfère ssh -R ou frp.
Depuis la machine locale : le port forwarding local
Une fois le port 8000 disponible sur le VPS, deux options pour le ramener en localhost:8000 sur ta machine.
Via le VPS (recommandé, sécurisé)
Même si le tunnel inverse est lié sur 127.0.0.1 du VPS (GatewayPorts no), ta machine locale peut s’y connecter :
ssh -L 8000:localhost:8000 user@IP_DU_VPSlocalhostici est résolu côté VPS : on atteint le127.0.0.1:8000du VPS, qui est précisément là oùssh -Ra exposé vLLM.- Aucun port n’est ouvert publiquement : c’est la variante la plus sûre.
En direct vers l’instance Vast.ai (sans VPS)
Vast.ai autorise le port forwarding local directement :
ssh -p PORT_SSH -i ~/.ssh/ma_cle_vast root@HOTE_VAST -L 8000:localhost:8000C’est le chemin le plus court (pas de VPS), mais il dépend de la stabilité de la connexion proxy Vast et de l’IP de l’instance.
Le raccourci Vast.ai pour les ports exposés
Quand tu exposes un port dans la console Vast.ai, la plateforme affiche un mapping du type :
Open Ports XX.XX.XX.XX:YYYY -> 8000/tcpCela correspond à la fonctionnalité « direct port » de Vast : tu peux alors joindre http://XX.XX.XX.XX:YYYY/v1 depuis l’extérieur, sans tunnel manuel. Le tunnel VPS reste utile quand tu veux une adresse stable, une IP fixe, ou que la machine n’offre pas de ports directs.
Étape 6 — Brancher VS Code
À ce stade, http://localhost:8000/v1 sur ta machine locale doit répondre. Vérifie avant d’ouvrir l’IDE :
curl http://localhost:8000/v1/modelsRésultat attendu : un JSON contenant "id": "qwen3-32b-abliterated" (ou le nom que tu as choisi via --served-model-name).
Extension Continue
Continue lit sa configuration dans ~/.continue/config.yaml (le config.json est déprécié mais toujours supporté). Point clé : le provider openai accepte un apiBase arbitraire — vLLM est explicitement listé comme compatible.
~/.continue/config.yaml :
name: Local Vast.ai
version: 0.0.1
schema: v1
models:
- name: Qwen3-32B-abliterated
provider: openai
model: qwen3-32b-abliterated # doit correspondre au --served-model-name
apiBase: http://localhost:8000/v1
apiKey: dummy # vLLM sans --api-key accepte n'importe quoi
roles:
- chat
- editÉquivalent config.json (déprécié) :
{
"models": [
{
"title": "Qwen3-32B-abliterated",
"provider": "openai",
"model": "qwen3-32b-abliterated",
"apiBase": "http://localhost:8000/v1",
"apiKey": "dummy"
}
]
}Dans VS Code : panneau Continue → sélectionne le modèle → chat.
Cline
Cline se configure via l’UI (pas de fichier). Chemin : Settings → Providers → API Provider = "OpenAI Compatible", puis :
Champ | Valeur |
|---|---|
Base URL |
|
API Key |
|
Model ID |
|
Clique ensuite « Verify » (bouton de test de connexion).
Pièges fréquents :
- Base URL sans
/v1→ échec silencieux. - Model ID qui ne correspond pas exactement au
--served-model-name. - Cline est un agent : il a besoin du function calling. vLLM doit être lancé avec le parser adapté à Qwen3 :
vllm serve huihui-ai/Qwen3-32B-abliterated \
--enable-auto-tool-choice --tool-call-parser hermes ...Sans ces flags, Cline pourra discuter mais ne pourra pas lire/éditer/exécuter de fichiers.
Roo Code
Configuration UI également : panneau Roo Code → Settings → API Provider = "OpenAI Compatible", puis :
Champ | Valeur |
|---|---|
Base URL |
|
API Key |
|
Model |
|
Important : Roo Code n’a pas de repli XML pour les outils — le modèle doit implémenter le schéma de function calling OpenAI, sinon il est inutilisable pour l’édition de code. Même exigence que Cline : lance vLLM avec --enable-auto-tool-choice --tool-call-parser hermes (ou qwen3_coder pour les variantes Coder).
Rappel de sécurité : pour Cline et Roo Code, qui envoient des prompts à un endpoint « OpenAI Compatible », le trafic transite en clair si l’URL est en
http://. Le tunnel SSH le chiffre de bout en bout (instance → VPS → machine locale), donc unapiBaseenhttp://localhost:8000est acceptable localement. Si tu exposes publiquement (frp/Cloudflare), passe en HTTPS et mets une vraie clé API.
L'exemple concret bout-en-bout
On va utiliser la configuration suivante, réaliste et testée :
- Instance Vast.ai : RTX A6000 48 Go (pour avoir de la marge).
- Modèle :
huihui-ai/Qwen3-32B-abliterateden quantification AWQ 4-bit (~19 Go de poids). - Serveur : vLLM avec les flags
--enable-auto-tool-choiceet--tool-call-parser hermes. - Tunnel :
ssh -Rvers un VPS, puisssh -Ldepuis la machine locale. - IDE : VS Code avec Continue.
Pourquoi cette config ? Un Qwen3-32B en BF16 pèse ~64 Go de poids : il ne tient pas sur une RTX 4090 (24 Go) ni sur une RTX A6000 (48 Go) en FP16. En 4-bit AWQ, il ne pèse plus que ~19 Go, ce qui tient largement sur une A6000 avec de la marge pour le cache KV et les activations.
Étape 0 — Prérequis
- Une instance Vast.ai RTX A6000 48 Go démarrée, avec sa commande SSH (
ssh -p PORT root@HOTE). - Un VPS (IP publique
1.2.3.4), utilisateurubuntu. - La clé publique de l’instance ajoutée au
~/.ssh/authorized_keysdu VPS.
Étape 1 — Se connecter à l’instance et lancer vLLM
# (1) Connexion à l'instance Vast.ai (adapter PORT et HOTE)
ssh -p PORT root@HOTE
# (2) Mettre à jour les paquets et installer les dépendances
apt-get update && apt-get install -y python3-pip git
# (3) Installer vLLM
pip install vllm
# (4) Authentification HuggingFace (pour accéder aux modèles huihui-ai)
huggingface-cli login
# Suis les instructions : copier-coller ton token HF depuis https://huggingface.co/settings/tokens
# (5) Lancer le serveur vLLM (Qwen3-32B-abliterated en AWQ 4-bit)
vllm serve huihui-ai/Qwen3-32B-abliterated \
--host 0.0.0.0 \
--port 8000 \
--served-model-name qwen3-32b-abliterated \
--max-model-len 65536 \
--gpu-memory-utilization 0.92 \
--tensor-parallel-size 1 \
--enable-auto-tool-choice \
--tool-call-parser hermes \
--quantization awqVérification sur l’instance :
# Attends que vLLM soit prêt (ça peut prendre quelques minutes au premier lancement)
curl http://localhost:8000/v1/models
# Doit retourner : {"object":"list","data":[{"id":"qwen3-32b-abliterated","object":"model",...}]}
# Test rapide avec une requête
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"qwen3-32b-abliterated","messages":[{"role":"user","content":"Bonjour, qui es-tu ?"}]}'
# Doit retourner une réponse JSON avec le texte du modèleÉtape 2 — Ouvrir le tunnel inverse vers le VPS
Ouvre un second terminal sur ta machine locale (ou un nouveau tmux sur l’instance) et lance :
# (6) Depuis l'instance Vast.ai, ouvrir un tunnel inverse vers le VPS
ssh -R 8000:localhost:8000 \
-o ServerAliveInterval=30 \
-o ServerAliveCountMax=3 \
-o ExitOnForwardFailure=yes \
ubuntu@1.2.3.4Note : si tu as configuré une clé SSH dédiée pour le VPS (comme expliqué plus haut), utilise
-i ~/.ssh/id_ed25519_vps.
Vérification sur le VPS :
# Connecte-toi au VPS et vérifie que le port est bien exposé
ssh ubuntu@1.2.3.4
curl http://localhost:8000/v1/models
# Doit répondre avec le même JSON qu'à l'étape 1Étape 3 — Ramener le port en local
Ouvre un troisième terminal sur ta machine locale et lance :
# (7) Sur TA machine locale, ramener le port 8000 du VPS vers localhost:8000
ssh -L 8000:localhost:8000 ubuntu@1.2.3.4Vérification en local :
# Sur ta machine locale
curl http://localhost:8000/v1/models
# Doit retourner le même JSON : la chaîne instance → VPS → local fonctionne
# Test avec une requête de chat
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"qwen3-32b-abliterated","messages":[{"role":"user","content":"Bonjour, qui es-tu ?"}]}'
# Doit retourner une réponse du modèleÉtape 4 — Brancher VS Code Continue
Crée ou édite le fichier ~/.continue/config.yaml sur ta machine locale :
name: Local Vast.ai
version: 0.0.1
schema: v1
models:
- name: Qwen3-32B-abliterated
provider: openai
model: qwen3-32b-abliterated
apiBase: http://localhost:8000/v1
apiKey: dummy
roles:
- chat
- editOuvre VS Code → panneau Continue → sélectionne Qwen3-32B-abliterated → tape « Bonjour » : la réponse arrive depuis la RTX A6000 de Vast.ai, à travers le VPS.
Étape 5 (bonus) — Rendre le tunnel permanent
Pour éviter de devoir relancer manuellement le tunnel à chaque reconnexion, configure un service systemd sur l’instance Vast.ai (comme expliqué dans la section 5) :
# Sur l'instance Vast.ai
sudo nano /etc/systemd/system/vllm-tunnel.serviceColle le contenu suivant (en adaptant IP_DU_VPS et le chemin de la clé SSH) :
[Unit]
Description=Tunnel inverse vLLM vers le VPS
After=network-online.target
Wants=network-online.target
[Service]
User=root
Environment=AUTOSSH_GATETIME=0
ExecStart=/usr/bin/autossh -M 0 -NT \
-o "ServerAliveInterval=30" \
-o "ServerAliveCountMax=3" \
-o "ExitOnForwardFailure=yes" \
-i /root/.ssh/id_ed25519_vps \
-R 8000:localhost:8000 ubuntu@1.2.3.4
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetPuis active le service :
sudo systemctl daemon-reload
sudo systemctl enable --now vllm-tunnel.service
systemctl status vllm-tunnel.service # doit afficher "active (running)"Désormais, le tunnel sera automatiquement relancé en cas de déconnexion ou de redémarrage de l’instance.
Variante économique : RTX 4090 + Huihui-Qwen3.8-27B
Si tu veux économiser, tu peux utiliser une RTX 4090 24 Go avec le Huihui-Qwen3.8-27B-abliterated en Q4_K_M (~17,5 Go) via Ollama.
Commandes adaptées :
# Sur l'instance Vast.ai (RTX 4090)
# (1) Installer Ollama
curl -fsSL https://ollama.com/install.sh | sh
# (2) Télécharger le modèle
ollama pull huihui_ai/Qwen3.8-abliterated
# (3) Servir avec un contexte de 64k
OLLAMA_CONTEXT_LENGTH=64000 ollama serveConfiguration Continue (~/.continue/config.yaml) :
models:
- name: Huihui-Qwen3.8-27B-abliterated
provider: openai
model: huihui_ai/Qwen3.8-abliterated
apiBase: http://localhost:11434/v1
apiKey: dummy
roles:
- chat
- editNote : Ollama ne supporte pas nativement le tool calling pour Qwen3. Pour utiliser Cline ou Roo Code avec des outils, il te faudra passer par vLLM (même sur une 4090, un 27B en 4-bit tient largement).
Conclusion
Tu as maintenant un agent IA non censuré, capable de comprendre le code, d’appeler des outils, de lire des fichiers et d’exécuter des commandes, le tout depuis ton VS Code local. Le tout pour quelques dollars de l’heure, avec la possibilité de tout éteindre quand tu as fini.
Ce setup a plusieurs avantages :
- Flexibilité : tu peux changer de modèle, de GPU, ou de configuration à tout moment.
- Contrôle : tu maîtrises complètement ton infrastructure, sans dépendre d’une API externe.
- Économie : tu ne paies que quand tu utilises le GPU, et tu peux optimiser les coûts avec des instances interruptibles.
Bien sûr, il y a des inconvénients :
- Complexité : il faut gérer soi-même le tunnel, la configuration, les mises à jour.
- Latence : le trafic passe par un VPS, ce qui ajoute un peu de latence (mais c’est négligeable pour un usage en développement).
- Maintenance : il faut surveiller les coûts, les crédits, les instances en cours.
Mais au final, c’est le prix à payer pour avoir un agent vraiment libre, sans censure, et adapté à tes besoins.
Et si tu te dis que c’est trop compliqué, rappelle-toi : il y a quelques années, faire tourner un modèle de langage de 30 milliards de paramètres sur son propre matériel était réservé aux géants du web. Aujourd’hui, c’est à la portée de n’importe qui avec une carte de crédit et un peu de patience.
Alors, prêt à coder avec un agent qui ne te dira pas « non » ?
Auteur
Krugz
Développeur fullstack
Développeur fullstack qui tente, tant bien que mal, de suivre l'actualité de l'IA au milieu d'une marée d'informations imbuvables et des milliers d'outils et de modèles qui sortent chaque jour.






