Proxmox 9 mit GPU für eine vLLM-VM konfigurieren
Eigene Sprachmodelle souverän im eigenen Rechenzentrum betreiben – ohne Cloud-Zwang. Diese Anleitung zeigt Schritt für Schritt, wie Sie unter Proxmox VE 9 eine NVIDIA-GPU per IOMMU/VFIO an eine virtuelle Maschine durchreichen und darin vLLM als hochperformanten, OpenAI-kompatiblen LLM-Server betreiben.
Das Wichtigste vorab
- Plattform: Proxmox VE 9.0 basiert auf Debian 13 „Trixie“, Linux-Kernel 6.14 und QEMU 10.
- Prinzip: Die GPU wird dem Host entzogen, an
vfio-pcigebunden und exklusiv an eine VM durchgereicht. - Gast: Ubuntu 24.04 LTS mit NVIDIA-Treiber und Docker – CUDA bringt das vLLM-Docker-Image selbst mit.
- Ergebnis: Ein
/v1/chat/completions-Endpunkt, der sich wie die OpenAI-API verhält – nur lokal und DSGVO-konform.
Architektur & Idee
Warum überhaupt eine VM? Weil die saubere Trennung zählt. Der Proxmox-Host bleibt schlank und kümmert sich nur um Virtualisierung, Storage und Netz. Die GPU wird ihm vollständig entzogen und ausschließlich einer VM überlassen. In dieser VM läuft die komplette KI-Welt – NVIDIA-Treiber, Docker und der vLLM-Container – isoliert, versionierbar und jederzeit als Ganzes sicherbar oder migrierbar.
vLLM ist eine Inferenz-Engine, die zwei Dinge besonders gut macht: Sie hält den GPU-Speicher dank PagedAttention effizient zusammen und bündelt viele gleichzeitige Anfragen per Continuous Batching. Nach außen spricht sie die OpenAI-API – Ihre bestehenden Werkzeuge, SDKs und RAG-Pipelines funktionieren ohne Umbau.
Voraussetzungen
Für ein verlässliches Passthrough brauchen Sie Hardware, die Virtualisierung der I/O-MMU unterstützt – das ist heute bei Server- und den meisten Desktop-Plattformen Standard:
- CPU: Intel mit VT-x und VT-d oder AMD mit AMD-V und AMD-Vi (IOMMU).
- Mainboard/BIOS: IOMMU-Unterstützung und idealerweise saubere IOMMU-Gruppen.
- GPU: Professionelle NVIDIA-GPU – RTX-Profiklasse (z. B. RTX 4000/5000/6000 Ada) oder Data-Center (L4, L40S, A100, H100) – mit genug VRAM für Ihr Modell.
- Software: Proxmox VE 9.0 frisch installiert und aktualisiert.
Prüfen Sie zunächst die Version und die CPU-Fähigkeiten direkt auf dem Host:
# Show the Proxmox version and kernel
pveversion -v | head -n 3
# CPU vendor and virtualisation flags
lscpu | grep -E "Virtualization|Vendor ID|Model name"
Hinweis: Planen Sie den VRAM nach dem Modell. Als Faustregel braucht ein Modell in 16-Bit etwa 2 GB pro Milliarde Parameter allein für die Gewichte – plus Reserve für den KV-Cache. Ein 8B-Modell passt komfortabel auf 24 GB; für 70B brauchen Sie mehrere Karten oder Quantisierung.
1.BIOS/UEFI vorbereiten
Aktivieren Sie im Firmware-Setup des Servers folgende Optionen (Bezeichnungen variieren je Hersteller):
- Intel VT-x / AMD SVM Mode – CPU-Virtualisierung.
- Intel VT-d / AMD IOMMU – Voraussetzung für Passthrough.
- Above 4G Decoding – nötig für moderne GPUs mit großen BARs.
- Re-Size BAR Support – falls vorhanden, für bessere Performance.
- Primary Display – möglichst auf die iGPU/„onboard“ stellen, damit die dedizierte GPU frei bleibt.
2.IOMMU im Kernel aktivieren
Proxmox VE 9 nutzt je nach Installation zwei verschiedene Bootloader: systemd-boot (bei ZFS-Root bzw. UEFI) oder GRUB. Mit einem Befehl finden Sie heraus, welcher aktiv ist:
proxmox-boot-tool status
Variante A – systemd-boot
Ergänzen Sie die Kernel-Befehlszeile in /etc/kernel/cmdline um die IOMMU-Parameter
(alles in einer Zeile) und schreiben Sie die Bootconfig neu:
# Intel CPU – append to the existing line:
root=ZFS=rpool/ROOT/pve-1 boot=zfs intel_iommu=on iommu=pt
# AMD CPU instead: amd_iommu=on iommu=pt
proxmox-boot-tool refresh
Variante B – GRUB
Bearbeiten Sie /etc/default/grub, ergänzen Sie die Parameter in
GRUB_CMDLINE_LINUX_DEFAULT und aktualisieren Sie GRUB:
# Intel:
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"
# AMD:
# GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on iommu=pt"
update-grub
reboot
Tipp: iommu=pt („pass-through“) lässt der IOMMU nur dort Arbeit, wo sie nötig
ist und kostet bei nicht durchgereichten Geräten keine Performance.
3.VFIO-Module laden
Tragen Sie die VFIO-Kernelmodule ein, damit sie beim Boot bereitstehen. Auf Kernel 6.14 zieht
vfio_pci die übrigen Module zwar automatisch nach – die explizite Liste schadet aber nicht:
vfio
vfio_iommu_type1
vfio_pci
4.IOMMU prüfen & Gruppen verstehen
Nach dem Neustart sollte die IOMMU aktiv sein. Das verifizieren Sie im Kernel-Log:
dmesg | grep -e DMAR -e IOMMU
# Expect, among others: DMAR: IOMMU enabled
dmesg | grep 'remapping'
# Expect: DMAR-IR: Enabled IRQ remapping (Intel)
# AMD-Vi: Interrupt remapping enabled (AMD)
Entscheidend für sauberes Passthrough sind die IOMMU-Gruppen. Eine Gruppe ist die kleinste Einheit, die sich isoliert durchreichen lässt. Eine GPU besteht meist aus zwei Funktionen – dem Grafik- und dem HDMI-Audio-Teil – die zusammengehören. Mit diesem kleinen Skript sehen Sie alle Gruppen:
#!/bin/bash
# Print all IOMMU groups and the PCI devices they contain
for g in /sys/kernel/iommu_groups/*/devices/*; do
n=${g%%/devices/*}; n=${n##*/}
printf 'IOMMU group %s: ' "$n"
lspci -nns "${g##*/}"
done | sort -V
vfio-pci – beide Funktionen einer Karte wandern gemeinsam in den Gast.Achtung: Liegen in der GPU-Gruppe noch fremde Geräte (z. B. ein USB-Controller),
lassen sie sich nicht trennen. Wechseln Sie dann den PCIe-Slot oder nutzen Sie – mit Bedacht und nur in
vertrauenswürdigen Umgebungen – einen ACS-Override (pcie_acs_override=downstream).
5.GPU an vfio-pci binden
Zuerst die exakten Geräte-IDs ermitteln. Die Form [10de:2204] ist die Hersteller-/Geräte-ID,
die wir gleich an vfio-pci übergeben:
lspci -nn | grep -Ei "nvidia|vga|audio"
# Example output:
# 01:00.0 VGA compatible controller [0300]: NVIDIA ... [10de:2204]
# 01:00.1 Audio device [0403]: NVIDIA ... [10de:1aef]
Nun binden wir beide IDs an vfio-pci und sorgen per softdep dafür, dass vfio-pci
vor jedem NVIDIA-Treiber greift:
# Bind the GPU (VGA) + audio function firmly to vfio-pci
options vfio-pci ids=10de:2204,10de:1aef
# vfio-pci must load before the NVIDIA drivers
softdep nouveau pre: vfio-pci
softdep nvidia pre: vfio-pci
softdep nvidiafb pre: vfio-pci
softdep drm pre: vfio-pci
Zusätzlich verbannen wir die Host-Treiber per Blacklist, damit der Proxmox-Host die Karte gar nicht erst anfasst:
blacklist nouveau
blacklist nvidia
blacklist nvidiafb
blacklist nvidia_drm
update-initramfs -u -k all
reboot
Nach dem Reboot prüfen Sie, dass tatsächlich vfio-pci die Karte hält – nicht nouveau oder nvidia:
lspci -nnk -s 01:00.0
# Kernel driver in use: vfio-pci <-- exactly what you want
6.VM erstellen (q35 + OVMF)
Für PCIe-Passthrough braucht die VM den q35-Maschinentyp und OVMF (UEFI) statt SeaBIOS. Sie können die VM in der Weboberfläche anlegen – hier der reproduzierbare CLI-Weg:
# New VM with the q35 chipset and UEFI/OVMF
qm create 100 \
--name vllm-gpu \
--machine q35 \
--bios ovmf \
--cpu host \
--cores 8 --sockets 1 \
--memory 32768 \
--scsihw virtio-scsi-single \
--net0 virtio,bridge=vmbr0 \
--ostype l26
# Add the EFI disk (for UEFI variables) and the system disk
qm set 100 --efidisk0 local-lvm:1,efitype=4m,pre-enrolled-keys=0
qm set 100 --scsi0 local-lvm:80,ssd=1,discard=on
# Attach the Ubuntu Server ISO as a CD-ROM and set the boot order
qm set 100 --ide2 local:iso/ubuntu-24.04-live-server-amd64.iso,media=cdrom
qm set 100 --boot 'order=scsi0;ide2'
7.GPU durchreichen
Jetzt die GPU der VM zuweisen. Geben Sie nur die Geräteadresse ohne Funktionsnummer an
(0000:01:00) – dann werden beide Funktionen (.0 und .1) gemeinsam durchgereicht:
qm set 100 --hostpci0 0000:01:00,pcie=1,x-vga=1
# pcie=1 -> attach as a native PCIe device (requires q35)
# x-vga=1 -> use the GPU as the VM's primary display
Das Ergebnis landet in der VM-Konfiguration /etc/pve/qemu-server/100.conf und sieht dann etwa so aus:
machine: q35
bios: ovmf
cpu: host
hostpci0: 0000:01:00,pcie=1,x-vga=1
efidisk0: local-lvm:vm-100-disk-0,efitype=4m,pre-enrolled-keys=0,size=4M
scsi0: local-lvm:vm-100-disk-1,discard=on,size=80G,ssd=1
Profi- & Data-Center-GPUs: Diese Karten sind ausdrücklich für den Virtualisierungs- und Passthrough-Betrieb ausgelegt und benötigen keine Sonderbehandlung. Achten Sie auf den passenden Treiberzweig (Production Branch bzw. Data Center Driver) und auf ausreichende Kühlung passiv gekühlter Data-Center-Karten im Servergehäuse.
8.Gast: NVIDIA-Treiber installieren
Installieren Sie Ubuntu 24.04 LTS in der VM. Nach dem ersten Start sollte die GPU im Gast sichtbar sein:
# Did the GPU arrive in the guest?
lspci | grep -i nvidia
# Build tools and DKMS for the driver
sudo apt update && sudo apt install -y build-essential dkms
# Pick and install the recommended NVIDIA driver automatically
sudo ubuntu-drivers install
# or explicitly: sudo apt install -y nvidia-driver-570
sudo reboot
Nach dem Neustart muss nvidia-smi die Karte sauber anzeigen – das ist der Moment der Wahrheit:
nvidia-smi
# Shows driver version, GPU model, VRAM and running processes.
9.Docker & Container-Toolkit
vLLM betreiben wir als offiziellen Container – das bringt CUDA, PyTorch und alle Abhängigkeiten gebündelt mit und hält den Gast sauber. Dafür installieren wir Docker und das NVIDIA Container Toolkit, das die GPU in den Container durchreicht:
# Install Docker
curl -fsSL https://get.docker.com | sh
# NVIDIA Container Toolkit – add the package repository
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
| sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -fsSL https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
| sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt update && sudo apt install -y nvidia-container-toolkit
# Point Docker at the NVIDIA runtime
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
# Test: is the GPU visible inside a container?
docker run --rm --gpus all ubuntu nvidia-smi
Tipp: Binden Sie das Hugging-Face-Cache-Verzeichnis als Docker-Volume ein, damit
heruntergeladene Modelle erhalten bleiben und nicht die System-Disk füllen. Für gesperrte Modelle
(z. B. Llama) hinterlegen Sie ein Token über die Umgebungsvariable HF_TOKEN.
10.vLLM-Container starten
Ein einziger docker run-Befehl startet den OpenAI-kompatiblen Server: Er lädt das Modell,
richtet die HTTP-API ein und reserviert den GPU-Speicher. --gpus all reicht die GPU durch,
--ipc=host gibt vLLM ausreichend geteilten Speicher:
docker run -d --name vllm --gpus all --ipc=host \
-p 8000:8000 \
-v ~/.cache/huggingface:/root/.cache/huggingface \
-e "HF_TOKEN=dein-hf-token" \
vllm/vllm-openai:latest \
--model meta-llama/Llama-3.1-8B-Instruct \
--served-model-name llama3.1-8b \
--gpu-memory-utilization 0.90 \
--max-model-len 8192 \
--api-key "dein-geheimer-schluessel"
Verfügen Sie über mehrere GPUs, verteilt vLLM ein großes Modell per Tensor-Parallelität über die Karten:
# Shard the model across, say, 2 GPUs
docker run -d --name vllm --gpus all --ipc=host \
-p 8000:8000 -v ~/.cache/huggingface:/root/.cache/huggingface \
vllm/vllm-openai:latest \
--model Qwen/Qwen2.5-32B-Instruct \
--tensor-parallel-size 2 \
--gpu-memory-utilization 0.92 --max-model-len 16384
11.Dauerbetrieb mit Docker Compose
Für den Dauerbetrieb gießen wir den Container in eine docker-compose.yml – mit automatischem
Neustart, fester Konfiguration und sauberen Logs:
services:
vllm:
image: vllm/vllm-openai:latest
container_name: vllm
restart: unless-stopped
ports:
- "8000:8000"
volumes:
- ~/.cache/huggingface:/root/.cache/huggingface
environment:
- HF_TOKEN=dein-hf-token
ipc: host
command: >
--model meta-llama/Llama-3.1-8B-Instruct
--served-model-name llama3.1-8b
--gpu-memory-utilization 0.90 --max-model-len 8192
--api-key dein-geheimer-schluessel
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
docker compose up -d
docker compose logs -f vllm
12.Testen
Der Endpunkt verhält sich wie die OpenAI-API. Ein schneller Test mit curl:
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer dein-geheimer-schluessel" \
-d '{
"model": "llama3.1-8b",
"messages": [
{"role": "system", "content": "Du bist ein hilfreicher Assistent."},
{"role": "user", "content": "Erklaere PagedAttention in einem Satz."}
]
}'
Und dieselbe Anfrage mit dem offiziellen OpenAI-Python-SDK – nur die base_url ändert sich:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="dein-geheimer-schluessel",
)
resp = client.chat.completions.create(
model="llama3.1-8b",
messages=[{"role": "user", "content": "Hallo!"}],
)
print(resp.choices[0].message.content)
Wichtige vLLM-Parameter
| Parameter | Wirkung |
|---|---|
--gpu-memory-utilization | Anteil des VRAM, den vLLM belegen darf (0–1). Höher = größerer KV-Cache = mehr parallele Anfragen. Typisch 0.85–0.95. |
--max-model-len | Maximale Kontextlänge (Tokens). Begrenzt den KV-Cache-Bedarf pro Anfrage. |
--tensor-parallel-size | Verteilt ein Modell über mehrere GPUs (Anzahl der Karten). |
--served-model-name | Frei wählbarer Modellname für die API – entkoppelt vom Pfad/Repo. |
--quantization | Quantisierung (z. B. awq, gptq, fp8) – spart VRAM bei großen Modellen. |
--dtype | Rechengenauigkeit, meist auto (bf16/fp16). |
--api-key | Schützt den Endpunkt mit einem Bearer-Token. |
--max-num-seqs | Obergrenze gleichzeitig verarbeiteter Sequenzen (Batch-Breite). |
Performance-Tuning
- KV-Cache maximieren:
--gpu-memory-utilizationso hoch wie stabil möglich – mehr Cache bedeutet mehr Durchsatz bei parallelen Anfragen. - Kontext realistisch setzen: Ein unnötig hoher
--max-model-lenreserviert Cache, der dann für Parallelität fehlt. - Quantisierung: FP8 oder AWQ/GPTQ halbieren den Speicherbedarf großer Modelle bei geringem Qualitätsverlust.
- CPU-Pinning & NUMA: In der VM-Config CPU-Affinität setzen und die GPU am passenden NUMA-Knoten betreiben – das senkt Latenz spürbar.
- Hugepages: Für große Modelle reduzieren Hugepages den Speicher-Overhead des Gasts.
- Modell vorladen: Beim ersten Start wird das Modell aus dem Hub geladen – danach liegt es im gemounteten Hugging-Face-Cache-Volume und startet schnell.
Troubleshooting
| Symptom | Ursache & Lösung |
|---|---|
| VM startet nicht, „IOMMU not present“ | IOMMU im BIOS oder Kernel nicht aktiv. Schritte 1–2 prüfen, dmesg | grep IOMMU. |
vfio-pci hält die Karte nicht | Blacklist/softdep unvollständig oder Initramfs nicht neu gebaut. update-initramfs -u -k all, dann lspci -nnk. |
| „Cannot reserve … IOMMU group not viable“ | Fremde Geräte in der GPU-Gruppe. Anderen PCIe-Slot wählen oder ACS-Override (mit Bedacht). |
nvidia-smi findet keine GPU | Treiber fehlt/zu alt oder GPU nicht durchgereicht. Passenden Data-Center- bzw. Production-Branch-Treiber installieren und die hostpci0-Zuweisung prüfen. |
CUDA out of memory beim Start | --gpu-memory-utilization oder --max-model-len senken, ggf. Quantisierung nutzen. |
| API antwortet, aber langsam | Kontext zu groß, Batch zu klein oder GPU am falschen NUMA-Knoten. Siehe Tuning. |
Sicherheit & Betrieb
Ein lokaler LLM-Server ist ein produktiver Dienst – behandeln Sie ihn auch so. Drei Grundregeln:
- Netzwerk isolieren: Den Port 8000 nie offen ins Internet stellen. Betreiben Sie vLLM hinter einem Reverse-Proxy (TLS, Authentifizierung, Rate-Limiting) in einem abgetrennten Netzsegment.
- Zugriff schützen: Immer einen
--api-keysetzen und je Anwendung eigene Schlüssel vergeben. - Datenhoheit nutzen: Der entscheidende Vorteil – kein Prompt, kein Dokument verlässt Ihr Haus. Genau das macht den Ansatz DSGVO-konform und auditierbar.
Häufige Fragen
Welche NVIDIA-GPUs sind für diesen Aufbau geeignet?
Empfehlenswert sind professionelle Karten: die RTX-Profiklasse (z. B. RTX 4000/5000/6000 Ada) sowie Data-Center-GPUs wie NVIDIA L4, L40S, A100 oder H100. Sie bieten ECC-Speicher, hohe VRAM-Kapazität und sind für Dauerbetrieb und Virtualisierung ausgelegt.
Brauche ich im Gast ein CUDA-Toolkit?
Für den reinen Betrieb von vLLM nicht. Das offizielle vLLM-Docker-Image bringt CUDA, PyTorch und alle Abhängigkeiten gebündelt mit. Im Gast genügen der NVIDIA-Treiber und das NVIDIA Container Toolkit. Ein vollständiges CUDA-Toolkit ist nur nötig, wenn Sie eigene CUDA-Kernel kompilieren.
Kann ich mehrere GPUs an dieselbe VM durchreichen?
Ja. Jede GPU wird als eigenes hostpci-Gerät zugewiesen (hostpci0, hostpci1 …). In vLLM verteilen Sie das Modell anschließend per --tensor-parallel-size über die Karten.
Warum eine VM statt eines LXC-Containers?
Eine VM mit echtem PCIe-Passthrough bietet starke Isolation und exklusiven, treibernahen GPU-Zugriff. LXC mit geteilter GPU ist ressourcenschonender, vermischt aber Host- und Gast-Treiber und ist für eine saubere, mandantenfähige Trennung weniger geeignet.
Welche Hardware empfiehlt sich für den Produktivbetrieb?
Für Dauerlast und mehrere Nutzer sind Data-Center-GPUs (z. B. NVIDIA L4, L40S oder A100/H100) ideal – passiv gekühlt, ECC-Speicher, für 24/7 ausgelegt. Für Einstieg und Entwicklung genügt oft eine professionelle RTX-Karte (z. B. RTX 6000 Ada) mit reichlich VRAM.
Quellen
Externe Quellen, Stand August 2026 (öffnen in einem neuen Tab):
- Proxmox – Proxmox VE 9.0 (Debian 13, Kernel 6.14, QEMU 10)
- Proxmox VE Wiki – PCI(e) Passthrough (IOMMU/VFIO)
- vLLM – Installation auf NVIDIA-GPU
- vLLM – Betrieb mit Docker (vllm/vllm-openai)
- NVIDIA – Container Toolkit: Installation
Souveräne KI – ohne Cloud-Zwang
Sie möchten eigene Sprachmodelle sicher im eigenen Rechenzentrum oder in unseren Rechenzentren in Deutschland und Finnland betreiben? Wir planen, bauen und betreiben Ihre GPU-Infrastruktur und Inferenz-Plattform – herstellerunabhängig und DSGVO-konform.
Dieser Beitrag dient der allgemeinen Information. Befehle, Geräte-IDs und Versionsangaben sind Beispiele und an Ihre Hardware anzupassen. Stand: August 2026, Proxmox VE 9.0.