
Sechzig Container auf einem Server
Eine Bare-Metal-Box führt Dutzende bis Hunderte von Hoody-Containern aus. KSM und BTRFS-Dedup machen die Marginalkosten nahezu null.
Du betreibst ein 70B-Modell auf einer einzelnen GPU-Box. Fünfzig nachgelagerte Container in deiner Flotte brauchen für dieselbe Anfrage dieselbe Antwort – sie scoren denselben Katalog, erzeugen dieselben Embeddings, werten dasselbe Experiment aus. Bezahl nicht für fünfzig Inferenzen. Lass das Modell einmal laufen, broadcaste die Tokens.
# generate once, pipe upwardllama.cpp -m llama3-70b.gguf \ -p "$PROMPT" --stream \ | curl -T - \ /pipe/llm?n=50pipe/llm?n=50EIN PFAD · FÜNFZIG READERdas Modell läuft einmal · die Pipe broadcastet · langsame Worker bremsen nur sich selbst
Die naive Antwort ist ein HTTP-Server mit Queue, Request-Batching und Lock-Contention. Die billigere Antwort für diese Form: Jede Anfrage geht auf einen Pipe-Pfad mit ?n=50. Das Modell läuft einmal. Fünfzig Consumer-Container holen denselben Pfad per GET ab und streamen dieselben Tokens zur selben Zeit, von der Pipe gefannt-out. Ein langsamer Worker bremst nur seine eigene Verbindung – die anderen bleiben auf voller Geschwindigkeit.
# 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 schickt Bytes nach oben. GET zieht sie nach unten. Der ?n=50-Parameter sagt, auf wie viele Reader gewartet werden soll; die Pipe hält die Verbindung, bis so viele verbunden sind, dann fannt sie den Stream gleichzeitig an alle aus. Keine Queue, keine Batching-Schicht, kein Inference-Server-mit-Loadbalancer.
Fünfzig nachgelagerte Container wollen dieselbe Antwort; du erzeugst sie einmal auf der GPU. Die Pipe übernimmt die Auslieferung. Kein Request-Batching-Framework, keine Token-Caching-Schicht, keine „bitte nicht nochmal laufen lassen“-Koordination.
Die Pipe blockiert, bis fünfzig Empfänger verbunden sind, dann streamt sie die Bytes des Producers parallel an jeden. Identische Kopien, Auslieferung in Leitungsgeschwindigkeit, null serverseitiger Speicher. Bis zu 256 Empfänger pro Pfad.
Wenn ein Consumer-Container gerade Garbage Collection macht oder seine Disk beschäftigt ist, hängt seine Verbindung. Die Pipe wendet Backpressure auf diesen Empfänger an – die anderen 49 streamen weiter mit voller Geschwindigkeit. Kein Head-of-Line-Blocking, kein Tuning der Queue-Tiefe.
Wenn fünfzig Container dieselbe Antwort wollen, rechnen die Alternativen pro Call, pro Token oder pro Inference-Server ab. Die Pipe rechnet einen HTTP-Transfer ab. Lass das Modell auf einer Box laufen, die du sowieso schon mietest.
Das ist nicht jeder Workload – es ist die Form, in der N Container dieselbe Antwort wollen. Wenn das deine Form ist, ist die Pipe das billigste Fan-Out, das du je verkabelst. Workloads mit divergierenden Prompts wollen weiterhin einen echten Inference-Server; dieses Pattern glänzt, wenn die Frage identisch und die Flotte breit ist.
Eine GPU, eine Pipe, fünfzig Container, die dieselben Tokens schmecken.
Jeder „gib meiner Flotte Zugriff auf ein Modell“-Stack, zu dem du greifst, wenn eine Anfrage viele Consumer versorgen muss. Jeder rechnet pro Call ab, hostet deine Weights oder erwartet, dass du einen Loadbalancer vor vLLM betreibst. Die Pipe broadcastet einmal.
Hör auf, fünfzig Inferenzrechnungen für eine Antwort zu zahlen. Lass das Modell dort laufen, wo du das Silizium sowieso schon mietest. Öffne eine Pipe. Lass die Flotte lesen.