le conteneur qui n'était pas là
Un de nos amis a une carte de 12 Go et une saine méfiance envers les logiciels. Quand nous lui avons proposé d'héberger, il n'a pas demandé ce qu'il gagnerait. Il a demandé : « bon, quelles images Docker allez-vous faire tourner sur mon PC ? »
C'est exactement la bonne question, et la réponse honnête l'a surpris : aucune. Pas « une petite », pas « une sandboxée ». Il n'y a pas d'image, pas de démon, pas de root. Arriver à cette réponse nous a pris quelques mois de conception, et ça vaut la peine de l'écrire — parce que le raisonnement s'applique à quiconque décide de ce qu'on demande à l'ordinateur d'un inconnu.
le design évident, et pourquoi nous ne l'avons pas livré
Toute pile de serving en 2026 se livre en conteneur. vLLM publie des images CUDA et ROCm ; comme tout framework d'inférence digne du nom. L'architecture évidente s'écrit toute seule : le plan de contrôle dit à l'hôte quelle image tirer, l'hôte la lance, tout le monde rentre chez soi.
Nous avons construit le plan, chiffré pour une machine domestique, et arrêté à la première ligne de l'estimation. Une image vLLM fait 10 à 30 Go. Par-dessus, l'hôte a besoin d'un runtime de conteneurs, d'un toolkit GPU, d'une plomberie de pilotes assortie, et — sur la plupart des distributions — d'une étape d'installation privilégiée. C'est une demande substantielle avant qu'un seul token soit servi, et beaucoup de surface sur une machine qui garde aussi les photos de quelqu'un.
Pendant ce temps, l'alternative était juste là. llama.cpp est un binaire d'~5 Mo. Un seul build — le Vulkan — sert les GPU AMD, NVIDIA et Intel depuis le même fichier. Il démarre en secondes, tourne comme utilisateur non privilégié, et n'écoute que localhost.
Pour les machines que nous voulons vraiment dans le pool — PC gamer, stations de travail, la RX 6900 XT sous un bureau — le binaire de 5 Mo n'est pas le compromis. C'est la meilleure ingénierie.
ce que nous avons fini par installer
Deux fichiers, et vous pouvez lire la source des deux.
mahout est notre agent : un binaire Rust qui sonde le matériel, enrôle la machine avec un code à usage unique, télécharge et vérifie les poids, supervise le moteur, réclame du travail et signe un reçu pour chaque job. Environ 5 Mo, open source, sans root.
Le moteur est une release llama.cpp épinglée, téléchargée une fois et contrôlée contre un SHA-256 compilé dans le binaire mahout lui-même. Si le fichier qui arrive n'est pas le fichier épinglé, il est jeté et rien ne tourne.
C'est toute l'empreinte. Une machine hôte finit avec un agent, un moteur et des poids de modèles dans un répertoire de cache — le tout nommé, vérifié par checksum et supprimable en une commande.
là où les conteneurs gagnent leur place
Rien de tout ceci ne dit que les conteneurs ont tort. Ils ont tort ici, pour l'instant.
Quand une seule carte sert beaucoup de requêtes concurrentes, le batching continu et la paged attention de vLLM prennent nettement l'avantage. C'est une histoire de workstation et de datacenter — le tiers où une machine est achetée pour servir, pas empruntée entre deux sessions de jeu. Nous le voudrons, et l'architecture a déjà la couture : dans notre catalogue, le moteur appartient au build, pas à l'hôte. Ajouter vLLM, c'est ajouter une entrée, pas réécrire l'agent.
Quand ça arrivera, trois règles tiendront — les mêmes qui gouvernent déjà les poids :
- Épinglé par digest, jamais par tag.
vllm/vllm-openai@sha256:…est un ensemble d'octets précis.:latestest une promesse que quelqu'un d'autre peut changer en douce. - Sur liste blanche dans le client. La liste des images qu'un hôte peut lancer est compilée dans la release de mahout. Le plan de contrôle peut en demander une ; il ne peut pas en introduire une nouvelle. Même compromis, nous ne pourrions pas dire à votre machine de lancer quelque chose d'arbitraire — il faudrait livrer un nouveau binaire signé, en public, à la vue de tous.
- Zéro egress, poids en lecture seule. Le conteneur parle à mahout sur localhost et à rien d'autre.
« et les images, elles vivent où ? »
La question suivante de notre ami, naturellement. Là, nous nous sommes surpris nous-mêmes.
L'instinct de tout ingénieur infrastructure est de mettre en miroir : faire tourner son propre registre, tout tirer à travers lui, contrôler la chaîne d'approvisionnement. Nous avons failli. Puis nous avons demandé ce que le miroir d'une image amont achète vraiment, sachant qu'on la référence déjà par digest — et la réponse était : rien. Un digest est vérifié par le runtime à l'entrée. Si les octets correspondent au digest, ce sont les octets que nous avons testés, qu'ils viennent de Docker Hub ou d'un serveur dans notre propre rack. Ré-héberger ajouterait des dizaines de gigas de stockage, une histoire de backup et une histoire de monitoring, contre zéro garantie supplémentaire.
Donc nous ne mettons pas en miroir. Nous épinglons.
Il y a exactement un cas où nous ferons tourner notre propre registre, et ce n'est pas le contrôle de la chaîne — c'est que l'image sera la nôtre. Vérifier qu'un hôte a vraiment fait tourner le modèle qu'il déclare exige un build du moteur qui émet un engagement cryptographique sur ses propres activations pendant qu'il décode. C'est un moteur patché, donc une image que nous construisons nous-mêmes, donc un endroit où la publier : un registre européen, signé, épinglé par digest, exactement comme tout le reste. Construire cette infrastructure le jour où on en a besoin, plutôt que le jour où on imagine en avoir besoin, a été le thème discret de tout le projet.
à quoi ça ressemble de l'extérieur
Notre ami l'a installé en quatre minutes environ :
curl -fsSL https://elephantpool.ai/install-mahout.sh | sh
# Windows (PowerShell)
irm https://elephantpool.ai/install-mahout.ps1 | iex
mahout models
mahout up --code SON-CODE
mahout bench --model gpt-oss-20b
mahout models lui a dit ce que sa carte de 12 Go pouvait servir avant de s'engager sur un seul téléchargement. Le benchmark a mesuré ce qu'elle fait vraiment plutôt que ce qu'une table prédisait — et c'est cette mesure, pas notre estimation, que son dashboard affiche désormais en gains par heure de service.
Il n'a jamais installé Docker. Il n'a jamais tapé sudo. Et quand il voudra que ça disparaisse, mahout uninstall affiche un plan de suppression avec les tailles avant de toucher à quoi que ce soit.
C'est, au fond, tout l'argument. Un logiciel qui tourne sans surveillance sur le matériel de quelqu'un d'autre doit être assez petit pour être lu, épinglé assez serré pour être vérifié, et assez facile à retirer pour que partir ne soit jamais un combat.
Lire l'architecture complète · Ce qui tourne sur votre machine · Voir les modèles · Installer mahout
Read next
a GPU died mid-sentence. the sentence finished.
Consumer hardware disappears without notice — someone sits down at their PC, a breaker trips, Wi-Fi drops. Our streams now survive that: another machine picks the answer up mid-word, and the dead segment is billed to nobody.
one model, every card: how a 27b runs on 8 gb
Qwen3.8 27B ships in five builds, from Q5_K_M on a 24 GB card down to IQ2_XXS on 8 GB. Why we split models from builds, what quantization actually costs, and how a quantized KV cache doubled our context overnight.