Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Künstliche Intelligenz 02.06.2026 · 11 min Lesezeit

Offene LLMs selbst serven mit vLLM (Llama, Mistral, Hermes)

So servierst Du offene LLMs wie Llama, Mistral, Qwen und Hermes als OpenAI-kompatiblen Server: vLLM per Docker Compose, mit GPU, HuggingFace-Cache, Quantisierung und Tool-Calling.

Server-Racks im Rechenzentrum als Sinnbild für eine lokale Vektordatenbank

vLLM ist ein Hochdurchsatz-Server für offene Large Language Models (LLMs). Statt ein Modell wie Llama, Mistral, Qwen oder Hermes über eine Cloud-API zu nutzen, servierst Du es mit vLLM auf Deinem eigenen GPU-Server und sprichst es über eine OpenAI-kompatible HTTP-Schnittstelle an. Diese Anleitung zeigt Dir Schritt für Schritt, wie Du das offizielle Image vllm/vllm-openai per Docker Compose betreibst, Modelle persistent ablegst, VRAM über Quantisierung im Griff behältst und Hermes-Modelle mit Tool-Calling nutzt. Zielgruppe sind Admins im Mittelstand und ambitionierte Heimserver-Nutzer, die volle Datenkontrolle und hohen Durchsatz auf eigener Hardware wollen.

Wichtig zur Abgrenzung: vLLM ist auf GPU-Serving mit hohem Durchsatz ausgelegt (PagedAttention, Batching) und braucht praktisch eine NVIDIA-GPU. Wenn Du nur einen einzelnen Nutzer auf CPU bedienen willst, ist Ollama mit Open WebUI die leichtgewichtigere Wahl. vLLM lohnt sich, sobald Du viele parallele Anfragen, niedrige Latenz und eine echte OpenAI-API als Backend brauchst.

Voraussetzungen

Bevor es losgeht, sollte folgendes vorhanden sein:

  • NVIDIA-GPU mit CUDA Compute Capability >= 7.0 (z. B. T4, A10, A100, H100, RTX 30xx/40xx). Ältere Karten werden nicht unterstützt.
  • VRAM-Faustregel: Ein 7B-Modell braucht in FP16 rund 16 GB, quantisiert (AWQ/GPTQ, 4 Bit) etwa 6 bis 8 GB. 13B liegen bei ca. 26 GB FP16, 70B laufen nur quantisiert oder über mehrere GPUs. Für den Produktivbetrieb sind mindestens 24 GB VRAM empfehlenswert.
  • Linux-Server mit Debian 12 oder Ubuntu 24.04, aktuellem NVIDIA-Treiber, Docker und Docker Compose. Grundlagen dazu findest Du in unserer Anleitung zu Docker Compose und Stacks.
  • Das nvidia-container-toolkit (richten wir in Schritt 1 ein), damit Container per --gpus all auf die GPU zugreifen können.
  • Ein HuggingFace-Account und Access-Token (HF_TOKEN), falls Du gated Modelle wie meta-llama/* nutzen willst. Die Modell-Lizenz musst Du vorher auf huggingface.co akzeptieren.
  • Optional eine Domain und ein Reverse-Proxy, wenn Du die API über HTTPS erreichbar machen willst (siehe Schritt 8).

Schritt 1: GPU-Zugriff für Docker einrichten

Damit Container die GPU sehen, brauchst Du das nvidia-container-toolkit. Der NVIDIA-Treiber selbst muss bereits installiert sein (prüfbar mit nvidia-smi auf dem Host). Installiere und konfiguriere das Toolkit unter Debian/Ubuntu so:

# NVIDIA-Container-Toolkit-Repository einbinden
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

# Installieren und Docker-Runtime konfigurieren
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker && sudo systemctl restart docker

Prüfe danach, ob ein Container die GPU wirklich sieht:

# GPU-Zugriff im Container verifizieren
docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi

Wenn hier die Ausgabe von nvidia-smi mit Deiner Karte erscheint, ist die Grundlage gelegt. Schlägt der Befehl fehl, ist meist der Treiber oder die Runtime-Konfiguration das Problem (siehe Troubleshooting).

Schritt 2: Projektverzeichnis und .env anlegen

Lege ein eigenes Verzeichnis für den Stack an und darin eine .env-Datei für den HuggingFace-Token und einen optionalen API-Schlüssel. So landen Geheimnisse nicht direkt in der compose.yaml.

mkdir -p ~/vllm && cd ~/vllm

Datei .env anlegen (Werte anpassen). Den VLLM_API_KEY solltest Du als langes Zufallspasswort setzen, sobald die API über das lokale Netz hinaus erreichbar ist:

# ~/vllm/.env
HF_TOKEN=hf_DEIN-HUGGINGFACE-TOKEN
VLLM_API_KEY=DEIN-LANGER-ZUFALLS-API-KEY

Für gated Modelle (z. B. meta-llama/Llama-3.1-8B-Instruct) musst Du zusätzlich auf huggingface.co die jeweilige Modell-Lizenz akzeptieren, sonst scheitert der Download mit Fehler 401/403.

Schritt 3: compose.yaml erstellen

Jetzt die zentrale compose.yaml. Sie startet vLLM mit GPU-Zugriff, mountet den HuggingFace-Cache als benanntes Volume (damit Modelle persistent bleiben) und setzt ausreichend Shared Memory. Das gewählte Modell und die Engine-Argumente stehen unter command.

# ~/vllm/compose.yaml
services:
  vllm:
    image: vllm/vllm-openai:latest
    container_name: vllm
    restart: unless-stopped
    ports:
      - "8000:8000"
    volumes:
      - hf-cache:/root/.cache/huggingface
    environment:
      - HF_TOKEN=${HF_TOKEN}
      - VLLM_API_KEY=${VLLM_API_KEY}   # optional: API absichern
    ipc: host          # alternativ: shm_size: '8gb'
    command: >
      --model Qwen/Qwen2.5-7B-Instruct
      --served-model-name qwen2.5-7b
      --max-model-len 8192
      --gpu-memory-utilization 0.90
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

volumes:
  hf-cache:

Die wichtigsten Stellschrauben:

  • --model: HuggingFace-Repo-ID des Modells (Pflicht).
  • --served-model-name: Kurzer Alias, unter dem das Modell in der API und in curl-Aufrufen erscheint.
  • --max-model-len: Maximale Kontextlänge. Begrenzt direkt den VRAM-Bedarf; bei OOM-Fehlern zuerst reduzieren.
  • --gpu-memory-utilization: Anteil des GPU-Speichers (0 bis 1, Default 0.9). Achtung: 0.90 reserviert dauerhaft 90 % des VRAM.
  • ipc: host: Gibt vLLM genug Shared Memory. Ohne das (oder shm_size: '8gb') stürzt der Server ab, weil der Docker-Default nur 64 MB beträgt.

Für die Produktion solltest Du statt :latest eine feste Version pinnen, etwa vllm/vllm-openai:v0.10.0, damit ein Update nicht ungeplant Breaking Changes bringt. Auf AMD-Hardware gibt es die Variante vllm/vllm-openai-rocm:latest.

Schritt 4: vLLM starten und Logs prüfen

Stack im Hintergrund starten und beim ersten Mal die Logs verfolgen. Der erste Start dauert länger, weil das Modell von HuggingFace geladen wird (danach liegt es im Volume).

cd ~/vllm
docker compose up -d
docker compose logs -f vllm

Sobald in den Logs sinngemäß Application startup complete bzw. Uvicorn running on http://0.0.0.0:8000 erscheint, ist der Server bereit. Mit Strg+C verlässt Du nur die Log-Ansicht, der Container läuft weiter.

Schritt 5: Server testen (curl)

vLLM stellt eine OpenAI-kompatible API bereit. Es gibt kein Web-UI und keinen Login - es ist ein reiner API-Server. Prüfe zuerst Health und verfügbare Modelle:

# Health und geladene Modelle
curl http://localhost:8000/health
curl http://localhost:8000/v1/models

Dann ein echter Chat-Aufruf gegen /v1/chat/completions. Den Modellnamen setzt Du auf den Alias aus --served-model-name (oder die volle HF-ID):

curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer DEIN-LANGER-ZUFALLS-API-KEY" \
  -d '{"model":"qwen2.5-7b","messages":[{"role":"user","content":"Hallo, wer bist du?"}]}'

Den Header Authorization: Bearer ... brauchst Du nur, wenn Du VLLM_API_KEY gesetzt hast. Weitere Endpoints sind /v1/completions und /v1/embeddings.

Schritt 6: Modelle wählen - Llama, Mistral, Qwen und Quantisierung

Die HuggingFace-Repo-ID im --model-Argument entscheidet, welches Modell läuft. Ein Wechsel bedeutet: ID (und ggf. Alias) in der compose.yaml ändern, dann docker compose up -d. Einige Beispiele:

Modell (HF-ID)FamilieHinweis
meta-llama/Llama-3.1-8B-InstructMeta LlamaGated: HF_TOKEN und akzeptierte Lizenz nötig
mistralai/Mistral-7B-Instruct-v0.3MistralTeils gated; sehr effizient
Qwen/Qwen2.5-7B-InstructQwenOffen, guter Allrounder
Qwen/Qwen2.5-7B-Instruct-AWQQwen (AWQ)4-Bit-quantisiert, deutlich weniger VRAM

Reicht der VRAM nicht, nutze ein quantisiertes Modell. AWQ und GPTQ in 4 Bit senken den Speicherbedarf eines 7B-Modells grob auf 6 bis 8 GB. Du gibst das Verfahren über --quantization an:

# Quantisiertes Modell (AWQ) fuer wenig VRAM
docker run --runtime nvidia --gpus all -v ~/.cache/huggingface:/root/.cache/huggingface \
  -p 8000:8000 --ipc=host vllm/vllm-openai:latest \
  --model Qwen/Qwen2.5-7B-Instruct-AWQ --quantization awq --max-model-len 8192

In der compose.yaml würdest Du die beiden Zeilen entsprechend unter command ergänzen. Mögliche Werte für --quantization sind u. a. awq, awq_marlin, gptq, gptq_marlin, fp8, bitsandbytes, gguf und compressed-tensors. Hast Du mehrere GPUs, verteilt --tensor-parallel-size N ein großes Modell darüber.

Schritt 7: Hermes-Modelle mit Tool-Calling serven

Hermes von Nous Research sind offene, feingetunte Modelle auf Llama- bzw. Qwen-Basis. Sie nutzen das ChatML-Prompt-Format und sind besonders stark bei Tool-/Function-Calling und strukturiertem JSON-Output - ideal, wenn das LLM als Backend für Agenten oder Automatisierungen dient. Damit vLLM die Tool-Aufrufe korrekt parst, brauchst Du zwei zusätzliche Flags:

# Hermes mit Tool-/Function-Calling
docker run --runtime nvidia --gpus all -v ~/.cache/huggingface:/root/.cache/huggingface \
  --env "HF_TOKEN=$HF_TOKEN" -p 8000:8000 --ipc=host vllm/vllm-openai:latest \
  --model NousResearch/Hermes-3-Llama-3.1-8B --enable-auto-tool-choice --tool-call-parser hermes

Als Compose-Variante setzt Du das Modell und die Flags unter command:

    command: >
      --model NousResearch/Hermes-3-Llama-3.1-8B
      --served-model-name hermes-3-8b
      --enable-auto-tool-choice
      --tool-call-parser hermes
      --max-model-len 8192

Tool-Calling wird ab Hermes 2 Pro unterstützt (Hermes-2-Pro-* und Hermes-3-*). Finger weg von Hermes-2-Theta-*: laut vLLM-Doku ist dort die Tool-Call-Qualität durch den Merge-Schritt verschlechtert. Nimm lieber Hermes 2 Pro oder Hermes 3.

Schritt 8: Reverse-Proxy, HTTPS und API-Schutz

vLLM bringt keine Authentifizierung und kein Login mit. Bindest Du Port 8000 direkt ans Internet, ist Deine API offen für jeden. Sichere sie ab:

  • API-Key setzen: über VLLM_API_KEY (oder --api-key). Clients müssen dann den Header Authorization: Bearer ... senden.
  • Nicht direkt exponieren: Port 8000 per Firewall auf das interne Netz beschränken und einen Reverse-Proxy mit TLS davorsetzen.

Ein minimales nginx-Beispiel, das HTTPS terminiert und an vLLM weiterreicht:

server {
    listen 443 ssl;
    server_name DEINE-DOMAIN.de;

    ssl_certificate     /etc/letsencrypt/live/DEINE-DOMAIN.de/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/DEINE-DOMAIN.de/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_buffering off;   # wichtig fuer Streaming-Antworten
    }
}

Als Frontend kannst Du vLLM bequem als OpenAI-kompatibles Backend in LibreChat oder Open WebUI einbinden - dort trägst Du als Base-URL http://DEIN-SERVER:8000/v1 und den API-Key ein. Für eine komplette UI-Lösung lohnt der Blick auf unsere Anleitung zu Open WebUI im Docker-Betrieb.

Schritt 9: Update und Backup

Updates laufen über das übliche Compose-Muster - Image ziehen und Container neu erstellen:

cd ~/vllm
docker compose pull && docker compose up -d
docker compose logs -f vllm

Wenn Du eine feste Version gepinnt hast, änderst Du vorher den Tag in der compose.yaml. Prüfe nach einem Update die Logs, da sich Engine-Argumente zwischen Versionen umbenennen können.

Beim Backup sind drei Dinge relevant:

  • Die compose.yaml und die .env - die eigentliche Konfiguration. Diese gehören in ein Backup oder eine Versionsverwaltung.
  • Das Volume hf-cache mit den heruntergeladenen Modellgewichten. Sicherst Du es nicht, werden die Modelle beim nächsten Start neu von HuggingFace geladen (Zeit und Bandbreite).
  • Da Modelle reproduzierbar über ihre HF-IDs definiert sind, ist ein Volume-Backup oft optional - die IDs in der compose.yaml genügen, um den Stand wiederherzustellen.

Volume lokal sichern, z. B. so:

# HuggingFace-Cache-Volume als tar sichern
docker run --rm -v vllm_hf-cache:/data -v $(pwd):/backup alpine \
  tar czf /backup/hf-cache-backup.tar.gz -C /data .

Troubleshooting

Die häufigsten Stolpersteine beim vLLM-Betrieb:

  • Crash mit shm-/CUDA-OOM direkt beim Start: Fehlendes Shared Memory. Setze ipc: host bzw. shm_size: '8gb' in der Compose-Datei. Der Docker-Default von 64 MB reicht für PagedAttention/PyTorch nicht.
  • VRAM-OOM beim Laden des Modells: Modell oder Kontext zu groß. Nimm ein kleineres oder quantisiertes Modell (AWQ/GPTQ), reduziere --max-model-len und senke --gpu-memory-utilization (z. B. auf 0.85).
  • Download bricht mit 401/403 ab: Gated Modell. Prüfe, ob HF_TOKEN gesetzt ist und Du die Lizenz des Modells auf huggingface.co akzeptiert hast.
  • --gpus all schlägt fehl: nvidia-container-toolkit fehlt oder die Runtime ist nicht konfiguriert. Teste mit docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi und wiederhole bei Bedarf Schritt 1.
  • Modell wird bei jedem Neustart neu geladen: Der HF-Cache ist nicht persistent. Prüfe, ob das Volume hf-cache wirklich auf /root/.cache/huggingface gemountet ist.
  • Hermes ruft keine Tools auf: Es fehlen die Flags --enable-auto-tool-choice --tool-call-parser hermes, oder Du nutzt Hermes 2 Theta (degradierte Tool-Qualität).

Häufige Fragen

Brauche ich zwingend eine GPU?

Praktisch ja. vLLM ist auf GPU-Hochdurchsatz ausgelegt und setzt eine NVIDIA-Karte mit Compute Capability >= 7.0 voraus. Für CPU-Betrieb oder Einzelnutzer ist Ollama die passendere Lösung.

Wie viel VRAM brauche ich für ein 7B-Modell?

In FP16 rund 16 GB, quantisiert (AWQ/GPTQ, 4 Bit) etwa 6 bis 8 GB. Für 13B sind es ca. 26 GB FP16, 70B laufen nur quantisiert oder über mehrere GPUs. Für Produktion sind mindestens 24 GB VRAM empfehlenswert.

Ist vLLM wirklich OpenAI-kompatibel?

Ja. Die Endpoints /v1/chat/completions, /v1/completions, /v1/models und /v1/embeddings entsprechen der OpenAI-API. Du kannst bestehende OpenAI-Clients meist nur durch Ändern der Base-URL und des API-Keys umstellen.

Was unterscheidet Hermes von Llama oder Mistral?

Hermes sind feingetunte Varianten auf Llama-/Qwen-Basis von Nous Research. Sie nutzen ChatML und sind besonders stark bei Tool-/Function-Calling und JSON-Ausgabe - praktisch für Agenten und Automatisierungen, etwa als Backend für n8n-Workflows.

Sollte ich :latest oder eine feste Version nutzen?

Zum Ausprobieren ist :latest bequem. In Produktion solltest Du eine feste Version pinnen (z. B. vllm/vllm-openai:v0.10.0), weil :latest sich unangekündigt ändern und Breaking Changes oder umbenannte Argumente mitbringen kann.

Kann ich mehrere Modelle gleichzeitig serven?

Eine vLLM-Instanz bedient ein Modell. Für mehrere Modelle startest Du mehrere Container/Services mit unterschiedlichen Ports - genug VRAM vorausgesetzt - oder verteilst sie auf mehrere GPUs.

Fazit

Mit dem Image vllm/vllm-openai und einer überschaubaren compose.yaml betreibst Du offene LLMs wie Llama, Mistral, Qwen oder Hermes als schnellen, OpenAI-kompatiblen Server auf eigener Hardware. Die wichtigsten Punkte: GPU per nvidia-container-toolkit bereitstellen, Shared Memory über ipc: host setzen, den HuggingFace-Cache als Volume persistieren und den VRAM über Quantisierung und --max-model-len steuern. Sichere die API mit einem Key und einem Reverse-Proxy ab, bevor Du sie über das lokale Netz hinaus öffnest. Damit hast Du ein leistungsfähiges, datensouveränes LLM-Backend, das Du nahtlos in LibreChat, Open WebUI oder eigene Anwendungen einbindest.

Weiterführende Anleitungen und Quellen

Passende Anleitungen aus unserem Wissensbereich:

Quellen (offizielle vLLM-Dokumentation):