
Soixante conteneurs sur un seul serveur
Une machine bare-metal exécute des dizaines à des centaines de conteneurs Hoody. La dédupplication KSM et BTRFS rend le coût marginal quasi nul.
Vous faites tourner un modèle 70B sur une seule machine GPU. Cinquante conteneurs en aval dans votre flotte ont besoin de la même réponse pour la même requête — ils notent le même catalogue, génèrent les mêmes embeddings, évaluent la même expérience. Ne payez pas cinquante inférences. Faites tourner le modèle une fois, diffusez les tokens.
# generate once, pipe upwardllama.cpp -m llama3-70b.gguf \ -p "$PROMPT" --stream \ | curl -T - \ /pipe/llm?n=50pipe/llm?n=50UN CHEMIN · CINQUANTE LECTEURSle modèle tourne une fois · le pipe diffuse · les workers lents ne ralentissent qu'eux-mêmes
La réponse naïve, c'est un serveur HTTP avec une file d'attente, du batching de requêtes et de la contention de verrous. La réponse moins chère pour cette forme : chaque requête atterrit sur un chemin de pipe avec ?n=50. Le modèle tourne une fois. Cinquante conteneurs consommateurs font GET sur le même chemin et diffusent les mêmes tokens en même temps, distribués par le pipe. Un worker lent applique de la backpressure à sa propre connexion — les autres restent à pleine vitesse.
# 1× GPU box — run the model once and pipe its tokens upward.
llama.cpp -m llama3-70b.gguf -p "$PROMPT" --stream \
| curl -T - https://pipe.hoody.com/api/v1/pipe/llm?n=50
# 50 consumer containers — same path, ?n=50, fanned out by the pipe.
for i in $(seq 1 50); do
curl https://pipe.hoody.com/api/v1/pipe/llm?n=50 \
| jq -c .delta \
| ./score.py --worker $i &
done
# Sender blocks until 50 readers have connected, then bytes flow.
# Slow workers backpressure their own connection — others stay at line speed.PUT envoie les octets vers le haut. GET les tire vers le bas. Le paramètre ?n=50 indique combien de lecteurs attendre ; le pipe garde la connexion jusqu'à ce que ce nombre soit atteint, puis distribue le flux simultanément à tous. Pas de file d'attente, pas de couche de batching, pas de serveur-d'inférence-derrière-load-balancer.
cinquante conteneurs en aval veulent la même réponse ; vous la générez sur le GPU une seule fois. Le pipe gère la distribution. Pas de framework de batching de requêtes, pas de couche de cache de tokens, pas de coordination « surtout ne le relancez pas ».
le pipe se bloque jusqu'à ce que cinquante destinataires se connectent, puis diffuse les octets du producteur à chacun en parallèle. Copies identiques, livraison à pleine vitesse, zéro stockage côté serveur. Jusqu'à 256 destinataires par chemin.
si un conteneur consommateur fait du GC ou si son disque est occupé, sa connexion prend du retard. Le pipe applique de la backpressure à ce destinataire — les 49 autres continuent à pleine vitesse. Pas de blocage en tête de file, pas de réglage de profondeur de file.
Quand cinquante conteneurs veulent la même réponse, les alternatives facturent par appel, par token, ou par serveur d'inférence. Le pipe facture un seul transfert HTTP. Faites tourner le modèle sur une machine que vous louez déjà.
ce n'est pas tous les workloads — c'est la forme où N conteneurs veulent la même réponse. Quand c'est votre forme, le pipe est le fan-out le moins cher que vous câblerez. Les workloads à prompts divergents veulent toujours un vrai serveur d'inférence ; ce schéma brille quand la question est identique et la flotte est large.
Un GPU, un pipe, cinquante conteneurs goûtant les mêmes tokens.
Toutes les stacks « donne accès à un modèle à ma flotte » que vous attrapez quand une requête doit alimenter plusieurs consommateurs. Chacune facture par appel, héberge vos poids, ou vous demande de faire tourner un load balancer devant vLLM. Le pipe diffuse une fois.
Arrêtez de payer cinquante factures d'inférence pour une seule réponse. Faites tourner le modèle là où vous louez déjà le silicium. Ouvrez un pipe. Laissez la flotte lire.