# Eigenen LLM Endpoint aufsetzen: von der GPU zum ersten Token

Ein realistischer Weg vom blanken Server zum produktiven Inferenz-Endpoint. Die Schritte, die Reihenfolge und die Stolpersteine, die zwischen „läuft lokal“ und „läuft produktiv“ liegen.

## Die Frage hinter dem ersten Token

Ein Entwickler schrieb uns letzten Monat: „vLLM läuft, ich kriege Antworten, wir gehen nächste Woche live.“ Eine Woche später stand der Endpoint still, nicht weil das Modell schlecht war, sondern weil ein einziger Nutzer mit zwanzig parallelen Anfragen den Speicher gesprengt hatte, den auf der Demo niemand gerechnet hatte. Genau das ist der Punkt: Einen LLM-Endpoint zum **ersten Token** zu bringen ist an einem Nachmittag erledigt. Ihn so zu betreiben, dass er **produktive Last über Wochen** zuverlässig trägt, ist ein anderes Projekt. Die ehrliche Frage lautet darum nicht „wie starte ich vLLM“, sondern „was liegt zwischen dem ersten Token auf meiner Maschine und einem Endpoint, dem ich Kunden zumute“. Dieser Beitrag geht den Weg in der Reihenfolge durch, in der er real passiert, und nennt an jedem Schritt den Fehler, der die meisten ersten Versuche kostet.

## Schritt 1: Hardware und VRAM ehrlich ausrechnen

Bevor du irgendetwas installierst, **rechne nach, ob dein Modell überhaupt in den Speicher passt**. Der Speicher für die reinen Modellgewichte ergibt sich aus **Parameterzahl mal Bytes pro Parameter**: In FP16 sind das 2 Bytes, bei 8-bit-Quantisierung 1 Byte, bei 4-bit rund 0,5 Bytes. Ein 70B-Modell braucht also in FP16 etwa **140 GB**, in 4-bit nur noch rund **35 GB**. Auf diese reine Gewichtsgrösse schlägst du grob den **Faktor 1,2** auf, um KV-Cache, Aktivierungen und Overhead der Engine abzudecken, unter Last eher mehr, weil jeder gleichzeitige Request zusätzlichen **KV-Cache** belegt.

Aus dieser Rechnung folgt direkt, was auf welche Maschine passt. Eine klassische Karte mit **24 GB** trägt bequem ein 7B- bis 13B-Modell in FP16 oder ein quantisiertes 30B-Modell, aber kein grosses Modell in voller Präzision. Eine [DGX Spark](/de/dgx-spark) mit **128 GB Unified Memory** trägt dagegen ein 70B-Modell in FP16 am Stück oder mehrere kleinere Modelle parallel, ohne dass du über PCIe nachladen musst. Die Modellwahl nach Aufgabe und Speicher haben wir in [Welches offene Modell für welche Aufgabe](/de/wissen/offene-modelle-auswahl) ausgeführt; an dieser Stelle zählt nur die nüchterne Rechnung, ob **Gewichte plus Cache plus Overhead** unter dein VRAM-Budget passen.

Und genau hier liegt der teuerste Anfängerfehler: **nur die Gewichte zu rechnen und den KV-Cache zu vergessen**. Ein Modell, das beim Start mit einem einzelnen Request läuft, kippt unter zwanzig gleichzeitigen Anfragen in den **Out-of-Memory**, weil der Cache mit der Zahl und Länge der Sessions wächst, der Fall vom Entwickler oben. **Rechne den Betriebsfall, nicht den Demofall.**

## Schritt 2: Treiber und Laufzeit sauber aufsetzen

Der unspektakuläre Teil, an dem trotzdem die meisten ersten Versuche scheitern. Du brauchst den passenden **NVIDIA-Treiber**, ein **CUDA-Toolkit** in einer Version, die deine Inference-Engine erwartet, und das **NVIDIA Container Toolkit**, wenn du (dringend empfohlen) in Containern arbeitest. Treiber und CUDA-Laufzeit müssen zueinander passen, und die Engine bringt ihrerseits eine Erwartung an die CUDA-Version mit. **Diese drei in Einklang zu halten** ist die eigentliche Aufgabe dieses Schritts.

Warum **Container statt blanker Installation**? Eine native Installation von Treiber, CUDA und Engine direkt aufs Host-System reisst dir früher oder später die Versionen auseinander, sobald du etwas aktualisierst. Mit dem Container-Ansatz bleibt **nur der Treiber auf dem Host**, während CUDA-Laufzeit und Engine im Image gekapselt sind. Das macht Updates und Rollbacks beherrschbar und ist der Grund, warum die offiziellen Engine-Images genau so ausgeliefert werden. Der klassische Fehler bleibt trotzdem der **Versionskonflikt zwischen Treiber, CUDA und Engine**: ein zu alter Treiber für ein neues CUDA, oder eine Engine, die eine andere CUDA-Minor-Version erwartet. Prüf nach der Installation mit `nvidia-smi`, dass Treiber und CUDA-Version erkannt werden, und wähle das Engine-Image passend dazu, **statt blind das neueste Tag zu ziehen**.

## Schritt 3: die Inference-Engine wählen und starten

Jetzt kommt die Schicht, die das Modell tatsächlich serviert, und welche Engine passt, **hängt am Lastprofil, nicht an der Mode**. Für einen Endpoint mit echter Parallel-Last ist **vLLM** meist die richtige Wahl: hoher Durchsatz dank **Continuous Batching**, eine **OpenAI-kompatible API** und Tensor-Parallelismus, um grosse Modelle über mehrere GPUs zu legen. Du startest es als Container, zeigst ihm die GPU und übergibst Modell sowie die zentralen Flags, nämlich `--tensor-parallel-size` für die Zahl der GPUs, `--max-model-len` für die maximale Kontextlänge und `--gpu-memory-utilization` für den Anteil des VRAM, den die Engine belegen darf. **Diese drei Schrauben bestimmen, wie viele Nutzer parallel passen.**

Willst du dagegen nur schnell prüfen, ob ein Modell das Richtige tut, ist **Ollama** in Minuten startklar und läuft auch auf bescheidener Hardware. Für einen produktiven Endpoint mit vielen gleichzeitigen Nutzern ist es das **falsche Werkzeug**, weil das Batching schwächer ist. Die ganze Abwägung zwischen den Engines steht in [vLLM, Ollama oder TGI](/de/wissen/vllm-ollama-tgi-vergleich).

Beim Tuning lauert hier der Stolperstein: Ein zu hoch gesetztes `--max-model-len` **sprengt den KV-Cache-Speicher**, denn die Engine reserviert Cache für die volle Kontextlänge mal die Zahl paralleler Sequenzen, und schon ein scheinbar harmloser Wert lässt die Reservierung explodieren. Ebenso treibt ein zu hohes `--gpu-memory-utilization` die Maschine beim Warmup in den **OOM**. **Taste dich von konservativen Werten nach oben**, statt am Limit zu starten.

## Schritt 4: das Modell laden

Jetzt bekommt die Engine das Modell, das sie servieren soll, samt der Entscheidung über die Präzision. **Prüf, ob eine quantisierte Variante reicht**, bevor du in mehr VRAM investierst: **AWQ** und **GPTQ** sind verbreitete 4-bit-Formate für GPU-Inferenz, **GGUF** ist das Format aus der llama.cpp-Welt und eher für CPU- oder gemischte Setups. Eine gute 4-bit-Quantisierung spart **drastisch Speicher** bei oft kaum spürbarem Qualitätsverlust und lässt dadurch mehr Nutzer parallel zu.

Beim ersten Start lädt die Engine die Gewichte herunter und in den Speicher. Das **braucht Zeit**, belegt mehrere Dutzend Gigabyte auf der Platte und führt einen **Warmup** durch, bei dem CUDA-Graphen kompiliert werden. Plane diesen Vorlauf ein und häng ihn nicht an einen Health-Check, der schon nach Sekunden Alarm schlägt. Der Stolperstein hier ist der **Warmup-OOM**: Wenn Gewichte plus voller KV-Cache zusammen knapp über das VRAM-Budget gehen, kippt die Maschine genau in dem Moment, in dem du denkst, es läuft.

## Schritt 5: den Endpoint absichern

Jetzt antwortet dein Endpoint, und genau das ist das Problem, solange ihn jeder erreichen kann. Dieser Schritt **trennt das Spielzeug vom Produkt**. Leg einen **Reverse Proxy** davor, der **TLS** terminiert und den nackten Engine-Port nicht ins Netz lässt. Davor gehört eine **API-Key-Authentifizierung**, sonst betreibt früher oder später jemand anderes dein Modell auf deine Rechnung: ein offener, ungesicherter Inferenz-Port ist kein theoretisches Risiko, sondern **wird im Internet aktiv gescannt**.

Dazu kommen Limits und ein bewusstes Überlastverhalten: **Rate-Limits pro Schlüssel**, ein **Concurrency-Limit** für die Engine, **Timeouts** und ein Request-Size-Limit für überlange Prompts. Entscheide bewusst, was bei Überlast passieren soll, eine begrenzte **Warteschlange**, die Requests puffert, oder ein sauberes **429**, das dem Client sagt, er möge es später versuchen. Der gefährlichste Verzicht ist hier das **fehlende Timeout**: Ohne es blockiert eine einzige hängende Anfrage einen GPU-Slot und zieht die Latenz für alle anderen hoch.

## Schritt 6: Betrieb und Monitoring

Der Schritt, den alle unterschätzen, und der über die Zeit **teuerste**, denn ein Endpoint ist kein Projekt mit Ende, sondern **ein System, das gepflegt werden will**. Sichtbar aufs Dashboard gehören **GPU-Auslastung** und **VRAM-Verbrauch**, **Latenz als p50 bis p99**, **Fehlerrate** und **Tokens pro Sekunde**, typischerweise mit **Prometheus und Grafana**, gespeist aus `nvidia-smi` beziehungsweise **DCGM** und den Metriken der Engine. Dazu kommen **Health-Checks**, die den Endpoint regelmässig anfragen, und Alarme, die anschlagen, bevor Nutzer etwas merken. Du willst die Kapazitätsgrenze an **steigender p99-Latenz** erkennen, nicht am Support-Ticket.

Der zweite Teil des Betriebs ist **Update-Disziplin**. Engine-Versionen bringen Durchsatzgewinne und Bugfixes, Modelle werden abgelöst, und Sicherheits-Patches wollen zeitnah eingespielt sein. Jedes dieser Updates kann die **fragile Balance aus Treiber, CUDA und Engine** stören, weshalb du in einer **Staging-Umgebung** testest, bevor du Produktion anfasst. Diese Dauerpflege ist **der Block, der bleibt**, wenn der spannende Teil längst läuft.

## Was das realistisch kostet

Die Schritte 1 bis 4 schafft ein gutes Team an **ein bis zwei Tagen** bis zum ersten produktiven Token. Schritt 5 und vor allem Schritt 6, **Absicherung und stabiler Dauerbetrieb**, sind der Aufwand, der nie aufhört und der **die Rechnung dominiert**. Genau diesen Betriebsblock haben wir in den [Kosten eigener LLMs](/de/wissen/llm-selbst-betreiben-kosten) auseinandergenommen, weil er fast immer unterschätzt wird.

Deshalb die ehrliche Weggabelung am Ende. Willst du die **volle Kontrolle**, geben wir dir die Hardware [bare metal](/de/bare-metal) mit **Root-Zugang**, und du baust die Schichten 1 bis 6 selbst, so wie hier beschrieben. Willst du den **fertigen, souveränen Endpoint**, aber nicht den Betrieb erben, übernehmen wir mit [Managed Inference](/de/managed-inference) genau diese sechs Schichten: du bekommst eine **OpenAI-kompatible API in der Schweiz** und musst dich um Treiberkonflikte, KV-Cache-Tuning und nächtliche Alarme nicht kümmern. Im Zweifel **rechnen wir deinen konkreten Fall durch** und sagen dir, welcher Weg sich für deine Last lohnt.