J’ai commencé à utiliser des LLMs pour des tâches de scripting et de documentation il y a un an. Tout passait par des APIs externes. Puis j’ai réalisé que certaines de mes requêtes contenaient des extraits de configs avec des adresses IP internes, des noms d’hôtes, des structures de réseau. Pas de credentials en clair, mais assez pour me mettre mal à l’aise. J’ai voulu tester si l’inférence locale était utilisable sur le MS-01 sans GPU dédié.
Contraintes matérielles
heighliner est un Minisforum MS-01 i9-13900H (14 cœurs, 20 threads, 32 GB DDR5-5600). Il n’y a pas de GPU discret. Le slot M.2 2242 utilisable pour une deuxième carte n’a pas de carte GPU – les options eGPU sur ce châssis existent mais dépassent le budget actuel. L’inférence est donc entièrement CPU.
Ce n’est pas une configuration optimale pour les LLMs. Un GPU même modeste (RTX 3060, 12 GB VRAM) ferait du 40-80 tokens/s là où le CPU plafonne à 4-12 tokens/s selon le modèle. Mais c’est le matériel que j’ai, et le but est de savoir ce qui est utilisable dans ces conditions, pas de faire des benchmarks GPU.
Sur Proxmox VE 8.3, j’ai créé une VM Ubuntu 24.04 LTS dédiée à Ollama. Allocation : 4 vCPU, 16 GB RAM. Je ne lui en donne pas plus parce que heighliner fait tourner en parallèle les autres VMs du VLAN Serveurs (30) – K3s, monitoring, services web. 16 GB est le compromis entre « assez pour les modèles 7-9B » et « ne pas priver les autres ».
Installation
L’installation d’Ollama est simple. Le script officiel gère tout : dépendances, binaire, service systemd.
curl -fsSL https://ollama.com/install.sh | sh
Ce script exécute du code téléchargé depuis Internet avec les droits root. Lis-le avant de l’exécuter, surtout si la VM est sur le même VLAN que des services sensibles. Vérifie l’URL et le contenu sur https://github.com/ollama/ollama.
Après installation, le service ollama tourne automatiquement. Par défaut, il écoute uniquement sur 127.0.0.1:11434. C’est le comportement sûr – on y reviendra.
systemctl status ollama
# active (running) depuis l'installation
La version installée au moment de mes tests : Ollama 0.3.14. Le binaire est dans /usr/local/bin/ollama, le service systemd dans /etc/systemd/system/ollama.service.
Déplacer les modèles hors du disque système
Par défaut, Ollama stocke les modèles dans /root/.ollama/models/. Sur ma VM, le disque système est un volume de 40 GB sur le NVMe Kingston OEM PCIe 4.0 du MS-01 (/dev/sda). Llama 3.1 8B pèse ~4.7 GB en Q4_K_M, Gemma 2 9B pèse ~5.4 GB dans le même format. Si je charge plusieurs modèles, le disque système sature rapidement.
J’ai ajouté un second disque virtuel à la VM (50 GB sur le même pool Proxmox) monté sur /var/ollama. La configuration du chemin de stockage se fait via une variable d’environnement dans le service systemd :
# Éditer la configuration du service
systemctl edit ollama
Dans l’override, ajouter :
[Service]
Environment="OLLAMA_MODELS=/var/ollama/models"
systemctl daemon-reload
systemctl restart ollama
Vérifie que le répertoire existe et appartient à l’utilisateur `ollama` (créé automatiquement par le script d’installation) : `mkdir -p /var/ollama/models && chown ollama:ollama /var/ollama/models`
Télécharger les modèles
ollama pull llama3.1:8b
ollama pull gemma2:9b
ollama pull phi4-mini
Le téléchargement se fait depuis le registry Ollama. Chaque modèle est téléchargé en GGUF quantisé (Q4_K_M par défaut pour les tailles 8-9B), ce qui est le bon compromis taille/qualité pour l’inférence CPU.
ollama list
# NAME ID SIZE MODIFIED
# llama3.1:8b 365c0bd3c000 4.7 GB il y a 2 minutes
# gemma2:9b ff02c3702f32 5.4 GB il y a 8 minutes
# phi4-mini dd59a53c2d57 2.5 GB il y a 12 minutes
Benchmarks réels sur i9-13900H CPU-only
J’ai mesuré les tokens par seconde avec la commande intégrée d’Ollama, sur un prompt simple (« Explique la différence entre un bridge réseau et un switch en 3 phrases ») répété cinq fois par modèle, charge système idle par ailleurs.
Llama 3.1 8B (Q4_K_M) : entre 4 et 5 tokens/s. La qualité des réponses est bonne pour du texte technique en français. La latence pour obtenir les premiers tokens est d’environ 3-4 secondes (chargement du modèle en RAM). Une fois chargé, le modèle reste en mémoire jusqu’à ce qu’un autre modèle soit appelé ou que le timeout d’inactivité soit atteint.
Gemma 2 9B (Q4_K_M) : autour de 3 tokens/s. Plus lent que Llama 3.1 8B malgré une taille similaire – l’architecture de Gemma 2 utilise plus de mémoire bande passante par token. La qualité sur les tâches de raisonnement est légèrement meilleure selon mon ressenti subjectif, mais à 3 tokens/s une réponse de 200 tokens prend plus d’une minute.
Phi-4 Mini : environ 12 tokens/s. C’est le plus rapide de loin. Pour des tâches courtes – complétion de code, résumés courts, reformulation – c’est le seul modèle que j’utilise réellement en homelab. La qualité est inférieure aux deux autres sur les tâches complexes, mais pour « rédige le commentaire de cette fonction bash », c’est suffisant et ça répond en moins de 15 secondes.
Ces chiffres sont cohérents avec ce que d’autres homelabbers reportent sur des CPU de même génération. Le i9-13900H a 45 MB de cache L3, ce qui aide le débit mémoire interne pour les calculs matriciels.
L’API REST Ollama
Ollama expose une API HTTP compatible (partiellement) avec l’API OpenAI. L’endpoint principal pour la génération :
curl http://localhost:11434/api/generate \
-d '{
"model": "phi4-mini",
"prompt": "Qu'\''est-ce qu'\''un VLAN en 2 phrases ?",
"stream": false
}'
La réponse inclut le texte généré et les métriques de performance (eval_count pour le nombre de tokens, eval_duration pour la durée en nanosecondes). Pratique pour vérifier les débits.
L’endpoint /api/chat permet les conversations multi-tours avec un historique de messages, dans le même format que l’API OpenAI Chat Completions. C’est ce que les interfaces comme Open WebUI utilisent.
# Lister les modèles disponibles
curl http://localhost:11434/api/tags
# Vérifier que le service répond
curl http://localhost:11434/
# Ollama is running
Exposer l’API en local uniquement
Par défaut, Ollama écoute sur 127.0.0.1:11434, ce qui signifie qu’il n’est accessible que depuis la VM elle-même. Si tu veux y accéder depuis d’autres machines du VLAN (par exemple depuis un LXC Open WebUI sur la même machine), il faut lui faire écouter sur toutes les interfaces.
Changer `OLLAMA_HOST` à `0.0.0.0:11434` expose l’API sans aucune authentification sur tout le réseau accessible. Ollama n’a pas de système d’auth intégré. Toute machine qui peut atteindre le port 11434 peut générer du texte, charger des modèles, et consommer toute la RAM disponible. Fais ça uniquement sur un VLAN isolé et contrôlé, ou derrière un reverse proxy avec auth.
Pour autoriser l’accès depuis d’autres machines du VLAN Serveurs (30) uniquement, j’ai défini :
[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"
Environment="OLLAMA_MODELS=/var/ollama/models"
Et j’ai restreint l’accès au niveau du firewall de la VM Ubuntu (ufw) à la plage du VLAN 30 uniquement :
ufw allow from 10.10.30.0/24 to any port 11434
ufw deny 11434
Ce qui a coincé : les modèles 70B et la RAM
J’ai voulu tester Llama 3.1 70B quantisé Q4, qui pèse environ 40 GB. La VM a 16 GB de RAM – c’est évidemment insuffisant. Ollama tente quand même de charger ce qu’il peut en RAM et de swapper le reste. Résultat : le système swappe massivement, le débit tombe à moins de 0,2 tokens/s, et la VM est pratiquement inutilisable pendant le chargement. J’ai tué le processus après 10 minutes sans avoir vu une réponse complète.
Même en donnant 28 GB de RAM à la VM (au prix de priver les autres services), le modèle 70B Q4 ne tenait pas correctement. Il aurait fallu dépasser 32 GB pour que ce soit utilisable, et c’est toute la RAM physique du MS-01. Conclusion pratique : sur 16-32 GB RAM sans GPU, les modèles 7-9B sont le plafond raisonnable.
Le modèle Llama 3.1 70B Q4 téléchargé (40 GB) a aussi saturé le volume de données. J’ai dû le supprimer avec ollama rm llama3.1:70b pour récupérer l’espace.
Résultat honnête
Phi-4 Mini à 12 tokens/s est réellement utilisable pour des tâches courtes et répétitives – complétion de code bash, rédaction de commentaires, reformulation de paragraphes. Je l’utilise plusieurs fois par semaine pour ça.
Llama 3.1 8B à 4-5 tokens/s est utilisable pour des tâches plus complexes si tu n’es pas pressé. Une question qui demande 300 tokens de réponse prend environ une minute. C’est acceptable pour de la génération de documentation ou d’un script qu’on va relire de toute façon.
Gemma 2 9B à 3 tokens/s, je ne l’utilise plus vraiment. La différence de qualité par rapport à Llama 3.1 8B ne justifie pas la lenteur supplémentaire sur ma config.
Ce n’est pas compétitif avec Claude ou GPT-4 en qualité de raisonnement. Sur des tâches complexes – architecture système, debugging d’un problème multi-couches, rédaction structurée longue – les modèles locaux 7-9B font des erreurs que les grands modèles commerciaux ne font plus. C’est un fait, pas une critique : les modèles locaux ont un ordre de grandeur de moins de paramètres.
La valeur est ailleurs : confidentialité totale, zéro coût d’API, disponibilité hors ligne, et la satisfaction de faire tourner ça chez soi. Pour du scripting quotidien, c’est suffisant.
L’étape suivante est Open WebUI, une interface web qui donne à Ollama l’ergonomie d’un ChatGPT – historique de conversations, system prompts, gestion des modèles. C’est l’objet du prochain article.