J’utilise des LLMs comme assistants de code depuis début 2026. D’abord avec des API cloud, puis en local.
Ce qui a changé avec une RTX 3090, c’est la bascule vers un modèle de travail où la latence et la confidentialité deviennent moins pénalisantes. L’inférence locale devient crédible pour du code à partir de 24 Go VRAM.
Voici mon setup, les chiffres réels et ce qui tient vraiment la route.
En bref#
- Machine : Debian forky/sid, 62 Go RAM, 16 cœurs, RTX 3090 (24 Go VRAM).
- Ollama 0.30.8, install officiel.
- opencode 1.17.7 connecté à
http://localhost:11434/v1, modèle par défautqwen3.6:27b-q4_K_M. - 5 modèles installés : Qwen 27b et 9b, Gemma 4 en 26b, 12b, et e4b.
- MCP SearXNG intégré pour la recherche web sans quitter opencode.
Pourquoi local plutôt que cloud#
J’ai fait l’inverse du mouvement général. Pas par idéologie mais par lassitude :
- latence réseau incompressible sur les API, même en région proche
- quotas et limites d’usage qui changent selon les offres
- données qui partent sur un serveur qu’on ne contrôle pas
- modèles qui changent sans prévenir, dégradation silencieuse de qualité
En local, la latence dépend surtout du GPU et la donnée ne quitte pas la machine. Le revers : il faut gérer le matériel, les drivers, les modèles et accepter une qualité inférieure aux meilleurs modèles cloud sur les tâches complexes.
Avec 24 Go VRAM, on se situe dans une gamme intéressante : les modèles 27b en Q4 tiennent, et pour du code, c’est suffisant dans la majorité des cas.
La machine#
OS : Debian forky/sid (kernel 6.19.10+deb14-amd64)
CPU : 16 cores
RAM : 62 Go DDR4
GPU : NVIDIA GeForce RTX 3090 (24 Go VRAM)
Driver : 550.163.01
CUDA : 12.4
Stockage : NVMe, chargement des modèles en ~2-3 secondesLa RTX 3090 a été achetée d’occasion. Avec 24 Go VRAM, elle reste une carte très intéressante pour de l’inférence locale amateur : assez de mémoire pour des modèles 27b quantizés, un écosystème CUDA mature, et une marge correcte pour le contexte. Une RTX 4090 est plus rapide, mais elle ne change pas le plafond VRAM : on reste à 24 Go.
Debian sid/forky bouge vite. Les versions de kernel, driver NVIDIA et paquets non-free peuvent changer d’une semaine à l’autre. Les commandes restent représentatives de mon installation, mais les numéros de version ne doivent pas être lus comme une recommandation figée.
Installation : Debian et NVIDIA#
La partie chiante de l’histoire. Sur Debian sid, l’installation NVIDIA demande de ne pas se tromper.
Driver NVIDIA#
sudo apt install nvidia-driver firmware-misc-nonfreeDebian forky utilise le driver 550 en natif dans les dépôts non-free. Plus besoin de télécharger depuis le site NVIDIA. Après installation, un redémarrage est nécessaire.
Vérification :
nvidia-smiÀ ce stade, CUDA 12.4 est disponible via le driver seul. Pas besoin du toolkit CUDA complet pour Ollama, le runtime inclus dans le driver suffit.
Ollama#
curl -fsSL https://ollama.com/install.sh | shLe script détecte automatiquement le GPU NVIDIA et configure le service systemd. La détection du GPU est un point de fragilité : si nvidia-smi ne fonctionne pas ou que les droits GPU ne sont pas accessibles, Ollama tombe en CPU sans prévenir clairement.
Vérification du service :
sudo systemctl status ollamaEt vérification de la détection GPU dans les logs :
sudo journalctl -e -u ollama | grep -i -E 'gpu|cuda|nvidia'Si tout est bon, Ollama expose l’API sur localhost:11434. Un test rapide permet de vérifier que l’API OpenAI-compatible répond :
curl http://localhost:11434/v1/modelsopencode#
opencode est installé via npm :
npm install -g opencode-ai
opencode --versionLa documentation officielle propose aussi un script d’installation. J’ai préféré npm ici parce que le binaire reste facile à mettre à jour et à retirer.
La configuration est dans ~/.config/opencode/opencode.json et pointe vers le provider Ollama local. Pas de clé API, pas de proxy, juste un baseURL local.
Les modèles#
J’ai installé cinq modèles. La RTX 3090 avec ses 24 Go VRAM charge un seul modèle à la fois, il faut donc composer entre polyvalence et spécialisation.
qwen3.6:27b-q4_K_M (17 Go) - le quotidien#
C’est mon modèle par défaut. En quantization Q4_K_M, il pèse environ 17 Go et tient dans la VRAM avec une marge de 5-6 Go pour l’expansion du contexte.
Tokenisation testée sur des fichiers de code réels (un projet Go de taille moyenne) :
| Contexte | VRAM observée | Commentaire |
|---|---|---|
| 8K tokens | ~18,5 Go | usage quotidien, confortable |
| 16K tokens | ~20 Go | OK, surveillance |
| 32K tokens | ~22,5 Go | chaud, frôle la limite |
| 48K tokens | swap CPU | dégradation marquée |
Pour du code, le 27b en Q4 donne des résultats solides : refactoring, explications de fonctions complexes, génération de squelettes de modules, révision de sécurité. La vitesse est correcte : entre 12 et 15 tokens/s selon la longueur de la réponse.
Limite réelle : au-delà de 32K tokens de contexte, la carte commence à saturer et le modèle ralentit. En pratique, c’est rarement un problème : un fichier de code en entier dépasse rarement 5-10K tokens.
qwen3.5:9b (6,6 Go) - le léger pour la vitesse#
Quand je veux une réponse rapide sans mobiliser tout le GPU : reformater un bout de YAML, corriger la syntaxe d’une commande, générer un script shell rapide.
Avantage : il charge en moins de 2 secondes et libère la VRAM quasi instantanément. Je l’utilise en parallèle d’autres tâches GPU sans contention.
Défaut : sur des sujets complexes (architecture, refactoring multi-fichiers), il perd le fil. La qualité baisse visiblement.
gemma4:26b (17 Go)#
Gemma 4 26B. Qualité générale comparable au Qwen 27b dans mon usage. Sur du code pur, je trouve Qwen un peu meilleur. Sur de la rédaction technique et de l’analyse, Gemma a parfois un avantage.
Je le garde en backup pour varier les réponses ou si je soupçonne un biais sur un prompt particulier. Comparer les deux modèles sur un même problème est instructif.
gemma4:12b (7,6 Go) et gemma4:e4b (9,6 Go)#
Gardés pour tests. Le 12b est un intermédiaire correct mais moins pertinent que le Qwen 9b pour du code. Le e4b est une variante “edge” orientée exécution locale légère ; dans mon workflow, il ne justifie pas encore sa place.
Performances mesurées#
J’ai fait tourner quelques benchmarks avec le qwen3.6:27b-q4_K_M :
| Modèle | Tokens/s (génération) | Latence 1er token | VRAM |
|---|---|---|---|
| qwen3.6:27b-q4_K_M | 13,5 t/s | ~800ms | 18,5 Go |
| qwen3.5:9b | 32 t/s | ~300ms | 7 Go |
| gemma4:26b | 11 t/s | ~950ms | 17,5 Go |
| gemma4:12b | 28 t/s | ~400ms | 8,5 Go |
Mesures prises avec un prompt standard de révision de code (un fichier Go de 200 lignes, génération de commentaires et suggestions). Température à 0. Les chiffres varient selon la charge du GPU et la température ambiante.
Pour référence, un LLM cloud comme Claude répond généralement en 200-500ms avec un débit bien supérieur. La différence est réelle. Mais en local, on ne partage pas la file d’attente et la latence est stable, pas soumise aux pics d’utilisation.
Configuration opencode#
La config est simple. Le fichier ~/.config/opencode/opencode.json :
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"ollama": {
"npm": "@ai-sdk/openai-compatible",
"name": "Ollama",
"options": {
"baseURL": "http://localhost:11434/v1"
},
"models": {
"qwen3.6:27b-q4_K_M": {
"name": "qwen3.6:27b-q4_K_M"
},
"qwen3.5:9b": {
"name": "qwen3.5:9b"
},
"gemma4:26b": {
"name": "gemma4:26b"
},
"gemma4:12b": {
"name": "gemma4:12b"
},
"gemma4:e4b": {
"name": "gemma4:e4b"
}
}
}
},
"model": "ollama/qwen3.6:27b-q4_K_M"
}Le provider utilise @ai-sdk/openai-compatible. Ollama implémente l’API OpenAI donc pas besoin de provider spécifique. Le baseURL sur localhost:11434/v1 et c’est opérationnel.
Changer de modèle en cours de session se fait avec une commande ou via l’interface interactive d’opencode.
Deux vérifications utiles avant d’accuser le modèle :
ollama ps
curl http://localhost:11434/v1/modelsLa première commande permet de voir le modèle chargé et l’occupation mémoire côté Ollama. La seconde vérifie que le nom déclaré dans opencode.json correspond bien à un modèle exposé par l’API locale.
Au moment du contrôle, ollama ps indiquait gemma4:12b comme modèle chargé. nvidia-smi remontait environ 9,15 Go de VRAM utilisée sur 24,58 Go. C’est cohérent avec un modèle de taille intermédiaire ; avec qwen3.6:27b-q4_K_M, l’occupation observée est nettement plus proche des 18-19 Go.
MCP SearXNG#
J’ai intégré SearXNG via MCP pour que opencode puisse faire des recherches web :
"mcp": {
"searxng": {
"type": "local",
"command": ["npx", "-y", "mcp-searxng"],
"environment": {
"SEARXNG_URL": "http://localhost:8080"
},
"enabled": true
}
}SearXNG tourne sur la même machine en conteneur. L’intégration permet à opencode d’aller chercher des informations actualisées (documentation, bugs, CVE, RFC) sans sortir du terminal. Le résultat est renvoyé dans le contexte du modèle qui peut l’exploiter directement.
Point de sécurité à ne pas oublier : un serveur MCP local est un processus lancé depuis la configuration opencode. Sur une machine personnelle, c’est pratique. Sur un dépôt inconnu ou partagé, il faut traiter cette configuration comme du code exécutable et la relire avant de lancer l’agent.
Déploiement SearXNG avec Docker Compose#
SearXNG tourne en conteneur sur la même machine. Configuration sans mot de passe, adaptée à une instance locale :
docker-compose.yml :
services:
searxng:
image: searxng/searxng:latest
container_name: searxng
restart: unless-stopped
ports:
- "127.0.0.1:8080:8080"
volumes:
- ./core-config:/etc/searxng
environment:
- SEARXNG_BASE_URL=http://localhost:8080/
- SEARXNG_SECRET=${SEARXNG_SECRET}
cap_drop:
- ALL
cap_add:
- CHOWN
- SETGID
- SETUID.env :
SEARXNG_SECRET=change-me-with-a-random-secret
SEARXNG_BASE_URL=http://localhost:8080/Lancer avec docker compose up -d. Le volume core-config reçoit les fichiers de génération automatique au premier démarrage. SEARXNG_SECRET renseigne la clé serveur utilisée par SearXNG, mais il n’y a pas d’authentification : l’instance reste en accès libre. Le port est volontairement bindé sur 127.0.0.1 pour éviter une exposition LAN accidentelle.
Point important : le MCP SearXNG utilise l’API JSON de SearXNG. Par défaut, le format JSON peut être désactivé dans la configuration générée au premier démarrage. Il faut l’activer dans core-config/settings.yml :
search:
formats:
- html
- jsonSans le format JSON, le MCP ne reçoit rien et opencode retourne des erreurs silencieuses lors des recherches web. Le settings.yml se trouve dans le volume mounté. Après modification, le plus simple est de redémarrer le conteneur pour être certain que la configuration est relue.
Sous cette forme, SearXNG ne consomme que quelques Mo RAM et zéro GPU. Le port 8080 suffit pour l’interface web et l’API utilisée par le MCP.
Gestion thermique et consommation#
C’est le point sous-estimé de l’inférence locale. Une RTX 3090 en charge, ça chauffe et ça consomme.
$ nvidia-smi
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 550.163.01 Driver Version: 550.163.01 CUDA Version: 12.4 |
|-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| 0 NVIDIA GeForce RTX 3090 On | 00000000:01:00.0 Off | N/A |
| 95% 74C P2 325W / 350W | 18995MiB / 24576MiB | 92% Default |
+-----------------------------------------------------------------------------------------+Chiffres relevés après 30 minutes d’utilisation continue avec qwen3.6:27b :
- Température : 74°C, ventilateur à 95%
- Consommation : 325W sur 350W max
- Occupation VRAM : 19 Go / 24 Go
- GPU-Util : 92%
Si la carte est dans un boîtier fermé avec une ventilation moyenne, elle monte vite à 80°C. Le throttling thermique commence à partir de 83°C sur la plupart des modèles RTX 3090.
En pratique ça veut dire :
- Le boîtier doit être ouvert ou bien ventilé
- Les sessions longues peuvent saturer la pièce en chaleur
- La consommation électrique n’est pas négligeable (environ 2,5 kWh par journée intensive)
Un modèle plus petit comme le qwen3.5:9b consomme environ 150-180W et chauffe moins, ce qui peut justifier son usage pour des sessions longues où la qualité maximale n’est pas nécessaire.
Workflow quotidien#
opencode fonctionne comme un assistant dans le terminal. Mon usage typique :
- Révision de code : je colle un fichier ou une fonction, je demande une revue. qwen3.6:27b identifie les problèmes de logique, les erreurs potentielles et les améliorations.
- Génération de code : décrire ce qu’on veut en langage naturel, opencode génère le squelette. Utile pour les scripts bash, les règles Ansible, les manifests Kubernetes.
- Exploration de codebase : opencode comprend le projet, navigue dans les dépendances, trouve les patterns d’erreur.
- Debug : coller une stack trace, demander une analyse. Le gain de temps est réel.
- Recherche web via MCP : pour une question sur une API récente ou une CVE, SearXNG va chercher l’info et le modèle l’analyse.
Ce qui marche le moins bien : les tâches qui nécessitent une vue d’ensemble sur une large codebase. En dessous d’un certain nombre de fichiers, opencode gère. Au-delà (monorepo, projet avec 50+ fichiers), le contexte devient trop grand pour le 27b et la qualité baisse.
Ce que j’aurais fait différemment#
Après trois mois d’utilisation quotidienne :
- J’ai trop de modèles. Avec 24 Go VRAM, un seul chargé à la fois. Les modèles en trop ne font que prendre de la place disque (une quinzaine de Go chacun). Deux modèles suffisent : un gros (27b) et un petit (9b).
- Un alias ou un script pour décharger le modèle proprement.
ollama stop qwen3.6:27blibère la VRAM immédiatement. Pratique avant de lancer un jeu ou une autre tâche GPU. - La RAM système de 62 Go sert surtout quand le contexte dépasse la VRAM et qu’Ollama offload sur CPU. Ça marche mais c’est lent (on passe de ~13 t/s à ~3-4 t/s). Dans l’idéal, un modèle plus petit ou une quantization plus agressive éviterait ce cas.
- J’aurais dû mesurer les perfs plus tôt. Les tokens/s réels sont utiles pour calibrer ses attentes et choisir le bon modèle selon la tâche.
Ce qui ne marche pas#
- Les modèles 70b sont hors-limite. À moins d’accepter l’offloading CPU complet (quasi inutilisable).
- La gestion de contexte long (>32K tokens) est tendue. La VRAM devient le bottleneck.
- Les réponses multi-fichiers complexes sont moins bonnes qu’avec Claude ou GPT-4. Le modèle local n’a pas la même capacité à garder une vue d’ensemble.
- Pas de vision. Les modèles multimodaux (genre LLaVA) existent en local mais les 24 Go VRAM sont juste pour le texte ; ajouter de la vision réduit encore le contexte disponible.
- Pas de fine-tuning dans mon setup. C’est un sujet que je n’ai pas exploré mais qui mériterait un article séparé.
Script de mise à jour#
Garder les outils à jour est important, surtout pour la stack IA où les versions évoluent vite. Un script simple évite d’oublier l’un ou l’autre :
#!/bin/bash
# update.sh - Mettre à jour Ollama et opencode
set -euo pipefail
echo "=== Mise à jour Ollama ==="
curl -fsSL https://ollama.com/install.sh | sh
echo ""
echo "=== Redémarrage du service Ollama ==="
sudo systemctl restart ollama
sleep 2
sudo systemctl status ollama --no-pager
echo ""
echo "=== Mise à jour opencode ==="
npm update -g opencode-ai
opencode --version
echo ""
echo "=== Modèles disponibles ==="
ollama list
echo ""
echo "=== Services en cours ==="
curl -s http://localhost:11434/v1/models | python3 -m json.tool 2>/dev/null || echo "API Ollama non accessible"
echo ""
echo "=== VRAM ==="
nvidia-smi --query-gpu=temperature.gpu,memory.used,memory.total,power.draw,power.limit --format=csv,noheaderOn le lance après un chmod +x update.sh. Le script fait le job dans l’ordre : Ollama d’abord, puis redémarrage du service, ensuite opencode. La fin affiche l’état des modèles et la VRAM pour vérifier que tout est cohérent.
La sleep 2 après le restart est un minimum pratique. Sans elle, les commandes suivantes peuvent tomber sur un service qui n’a pas fini de s’initialiser. Ollama relit ses modèles au démarrage mais ne les recharge pas tous en mémoire : seulement le dernier utilisé reste chargé. Les autres sont disponibles mais en attente.
Conclusion#
Le combo opencode + Ollama + RTX 3090 est un assistant de code local crédible. Le qwen3.6:27b-q4_K_M fournit des réponses de qualité sur la majorité des tâches de développement. Le gain principal n’est pas la performance pure, les API cloud restent plus rapides, mais le contrôle : service local, données locales, modèle choisi explicitement.
Ce n’est pas un remplacement parfait des meilleurs modèles cloud. Mais pour du code, c’est suffisant, et le contrôle qu’on garde compense largement la différence de qualité dans l’usage quotidien.
Prochaine étape possible : passer à une configuration multi-GPU ou à une carte avec plus de VRAM pour débloquer les modèles 70b. Mais pour l’instant, avec ce qui tient dans 24 Go, le rapport qualité/tranquillité est bon.
Sources#
- Documentation OpenCode : https://opencode.ai/docs/
- Providers OpenCode, configuration Ollama : https://opencode.ai/docs/providers/
- Documentation Linux Ollama : https://docs.ollama.com/linux
- Modèle Ollama qwen3.6:27b-q4_K_M : https://ollama.com/library/qwen3.6%3A27b-q4_K_M
- Modèles Ollama qwen3.5 : https://ollama.com/library/qwen3.5
- Modèles Ollama Gemma 4 : https://ollama.com/library/gemma4
- Documentation SearXNG : https://docs.searxng.org/
- MCP SearXNG : https://github.com/ihor-sokoliuk/mcp-searxng
- Spécifications NVIDIA GeForce RTX 3090 : https://www.nvidia.com/fr-fr/geforce/graphics-cards/30-series/rtx-3090/




