11. November 2026 · VRAMfarm-Team
CUDA out of memory: So beheben Sie den Fehler in ComfyUI, bei LLMs und im Training
torch.OutOfMemoryError: CUDA out of memory. Tried to allocate 2.00 GiB.
GPU 0 has a total capacity of 23.65 GiB of which 1.12 GiB is free.
Of the allocated memory 20.10 GiB is allocated by PyTorch, and 1.31 GiB
is reserved by PyTorch but unallocated.
Diese Meldung sagt genau eines: In diesem Moment hat das Programm 2 GiB mehr Grafikspeicher angefordert, als übrig war. Die Karte ist in Ordnung, und sie ist auch nicht immer zu klein. Die meisten Fälle lösen Sie in wenigen Minuten mit einem von vier Hebeln: niedrigere Präzision, eine kleinere Arbeitseinheit (Batch, Auflösung, Kontext), Speicher freigeben, den etwas anderes belegt, oder Fragmentierung beheben. Funktioniert keiner davon, ohne Qualität oder Tempo zu ruinieren, ist eine größere Karte die günstigere Antwort.
Erst den Fehler lesen, dann etwas ändern
Jeder Teil der Meldung verrät etwas:
- „Tried to allocate 2.00 GiB“ ist die einzelne Anforderung, die gescheitert ist, nicht der Gesamtbedarf Ihres Jobs. Wenn Sie die Einstellungen nur leicht senken, verschiebt sich der Absturz womöglich nur ein paar Schritte nach hinten.
- „Total capacity of 23.65 GiB“ ist bei einer 24-GB-Karte normal. Der Treiber behält einen kleinen Teil des Speichers für sich, und der CUDA-Kontext belegt noch ein paar Hundert Megabyte, bevor Ihr Modell lädt.
- „Reserved by PyTorch but unallocated“ ist Speicher, den PyTorch hält, für diese Anforderung aber nicht nutzen kann. Geht es um Gigabytes, ist Fragmentierung das Problem; siehe unten.
- Zeilen wie „Process 1234 has 9.80 GiB memory in use“ bedeuten, falls vorhanden, dass sich ein anderer Prozess die Karte teilt.
RuntimeError: CUDA error: out of memory ohne Details kommt meist von einer Bibliothek wie cuBLAS oder einem eigenen Kernel, oft beim Start. Die Lösungen sind dieselben.
Mit nvidia-smi prüfen, was den Speicher belegt
Führen Sie nvidia-smi im Jupyter-Terminal oder per SSH aus. Entscheidend ist die Zeile pro GPU:
| 0 NVIDIA GeForce RTX 4090 ... | 21540MiB / 24564MiB | 97% Default |
Die erste Zahl ist der belegte Speicher, die zweite der Gesamtspeicher der Karte, dann die GPU-Last. So beobachten Sie das live, während Ihr Job läuft:
nvidia-smi --query-gpu=memory.used,memory.total,utilization.gpu --format=csv -l 1
Auf einem gemieteten Server ist die Prozessliste unten oft leer, obwohl Speicher belegt ist. Der Server ist ein Container, und nvidia-smi sieht über diese Grenze hinweg keine Prozessnamen. Nutzen Sie stattdessen ps aux | grep python.
Drei Dinge belegen häufig Speicher, ohne dass Sie damit rechnen:
- Der Cache von PyTorch. Freigegebene Tensoren bleiben zur Wiederverwendung reserviert, und nvidia-smi zeigt sie als belegt an.
torch.cuda.memory_allocated()zeigt, was wirklich genutzt wird,torch.cuda.memory_reserved(), was gehalten wird.torch.cuda.empty_cache()gibt den Cache zurück; das hilft nur, wenn ein anderer Prozess ihn braucht. - Ein anderer Prozess auf derselben Karte. Ein Jupyter-Kernel, der vor drei Zellen ein Modell geladen hat, ein altes ComfyUI, das noch läuft, ein Trainingsskript, das mittendrin abgestürzt ist. Starten Sie den Kernel neu oder beenden Sie die PID mit
kill. Stirbt Ihr Skript jedes Mal, wenn eine andere App auf der Karte startet, liegt es daran: Beide konkurrieren um denselben Speicher. - Die Reservierung von vLLM. vLLM nimmt sich beim Start standardmäßig 90 % der Karte. Alles, was Sie daneben starten, läuft in den Speichermangel.
ComfyUI, Flux und Wan: Lösungen der Reihe nach
Arbeiten Sie die Liste von oben nach unten ab und hören Sie auf, sobald es läuft:
- FP8- oder GGUF-Gewichte nutzen. Flux.1 dev in 16 Bit bringt allein an Gewichten etwa 24 GB mit, in FP8 etwa 12 GB. Sein Text-Encoder T5-XXL schrumpft in FP8 von etwa 9,5 GB auf etwa 5 GB. GGUF-Versionen (über die Nodes von ComfyUI-GGUF) gehen weiter: Q8 passt zu 16-GB-Karten, Q5 und Q4 passen auf 12 GB, und bei Q4 leiden feine Details. Unsere Flux-Vorlage liefert Flux.1 schnell bereits in FP8.
- VAE Decode durch VAE Decode (Tiled) ersetzen. Das Dekodieren am Ende ist ein klassischer Absturzpunkt, besonders bei großen Bildern und Video. Gekacheltes Dekodieren arbeitet in Stücken und kostet ein paar Sekunden.
- Die Batch-Größe senken in Empty Latent Image. Vier Bilder nacheinander brauchen etwa ein Viertel des Aktivierungsspeichers eines Batches von vier.
- Die Auflösung senken, dann hochskalieren. Der Speicher für Aktivierungen wächst mit der Pixelzahl: 2048×2048 hat viermal so viele Pixel wie 1024×1024. Erzeugen Sie in nativer Größe und nutzen Sie einen gekachelten Upscaler.
- Bei Video Frames oder Auflösung kürzen. Mit Wan 2.2 sparen Sie mehrere Gigabyte, wenn Sie von 81 auf 49 Frames oder von 720p auf 480p gehen. Das 14B-Modell besteht aus zwei 14B-Experten, die ComfyUI nacheinander lädt; auf Karten mit 24–32 GB verschiebt Block Swap in den Wan-Video-Wrapper-Nodes einen Teil des Modells in den Arbeitsspeicher.
- Offloading als letztes Mittel. Wenn Sie ComfyUI selbst starten, hält
--lowvramTeile des Modells im Arbeitsspeicher, und--reserve-vram 2lässt 2 GB für anderes frei. Rechnen Sie damit, dass die Generierung um ein Mehrfaches langsamer wird.
Die Buttons des Managers zum Entladen von Modellen und Leeren des Caches helfen, wenn Sie in einer Sitzung zwischen Workflows wechseln, etwa von Flux zu Wan, denn das alte Modell kann geladen bleiben.
LLMs: Gewichte plus KV-Cache
Ein Sprachmodell braucht Speicher für drei Dinge: die Gewichte, den KV-Cache und 1–2 GB Arbeits-Overhead.
Gewichte sind Parameter mal Bytes pro Parameter:
| Modell | 16 Bit | FP8 / 8 Bit | 4 Bit |
|---|---|---|---|
| 8B | ~16 GB | ~8 GB | ~5 GB |
| 32B | ~66 GB | ~33 GB | ~20 GB |
| 70B | ~141 GB | ~71 GB | ~43 GB |
Der KV-Cache wächst mit jedem Token im Kontext, und zwar für jede Anfrage gleichzeitig. In 16 Bit belegt er etwa 128 KB pro Token bei Llama 3.1 8B, 256 KB bei Qwen3 32B und 320 KB bei Llama 3.x 70B. Eine einzige Unterhaltung mit 32.000 Tokens auf Qwen3 32B braucht etwa 8 GB Cache; eine mit 128.000 Tokens auf einem 70B-Modell etwa 42 GB, so viel wie die Gewichte in 4 Bit. Deshalb lädt ein Modell problemlos und scheitert dann an einem langen Chat oder wenn zehn Nutzer gleichzeitig kommen.
Lösungen nach Werkzeug:
- Ollama. Setzen Sie einen kürzeren Kontext mit
num_ctxoderOLLAMA_CONTEXT_LENGTH, und halbieren Sie den Cache mitOLLAMA_FLASH_ATTENTION=1undOLLAMA_KV_CACHE_TYPE=q8_0. Ollama stürzt selten ab; stattdessen verschiebt es Schichten auf die CPU. Zeigtollama psetwas wie35%/65% CPU/GPU, passt das Modell nicht und läuft um ein Mehrfaches langsamer. - llama.cpp. Begrenzen Sie den Kontext mit
-c 16384, legen Sie mit-nglfest, wie viele Schichten auf der GPU bleiben, und quantisieren Sie den Cache mit--cache-type-k q8_0 --cache-type-v q8_0. Ein quantisierter V-Cache braucht Flash Attention: Aktuelle Builds schalten sie automatisch ein, wo die GPU sie unterstützt, und-fa onerzwingt sie. - vLLM.
--gpu-memory-utilization(Standard 0.9) ist der Anteil am gesamten Speicher der Karte, den vLLM beim Start für Gewichte und Cache belegt. Senken Sie ihn auf 0.8, wenn der Start scheitert, weil etwas anderes die Karte nutzt. Meldet vLLM, dass die max seq len des Modells größer ist, als der KV-Cache speichern kann, erhöhen Sie auf 0.95 oder setzen Sie--max-model-len 32768.--kv-cache-dtype fp8halbiert den Cache,--max-num-seqsbegrenzt parallele Anfragen,--enforce-eagerspart den Speicher, den CUDA Graphs belegen, auf Kosten von etwas Tempo, und--tensor-parallel-size 2teilt das Modell auf zwei Karten auf. Die vLLM-Vorlage gibt Ihnen eine OpenAI-kompatible API, um diese Einstellungen auszuprobieren. - Die Gewichte quantisieren. Ein AWQ- oder GPTQ-Checkpoint in 4 Bit verkleinert die Gewichte auf etwa ein Viertel von 16 Bit. FP8 halbiert sie und läuft nativ auf Ada-, Hopper- und Blackwell-Karten.
Training: Batch, Aktivierungen und Optimizer verkleinern
Volles Fine-Tuning mit AdamW in Mixed Precision braucht vor den Aktivierungen etwa 16 Bytes pro Parameter: 2 für die Gewichte, 2 für die Gradienten, 4 für eine 32-Bit-Masterkopie und 8 für die Optimizer-Zustände. Ein 7B-Modell kommt auf etwa 112 GB, mehr als jede einzelne Karte außer H200 und B200 hat. Lösungen, grob danach sortiert, wie viel sie sparen und wie wenig sie kosten:
- Kleinerer Batch, gleicher effektiver Batch. Batch-Größe 2 mit 8 Schritten Gradient Accumulation trainiert wie ein Batch von 16.
- Gradient Checkpointing. Aktivierungen werden im Backward Pass neu berechnet statt gespeichert. Das spart einen großen Teil des Aktivierungsspeichers und kostet 20–30 % Tempo. In Hugging Face:
gradient_checkpointing=True. - BF16 Mixed Precision auf jeder Karte ab Ampere.
- 8-Bit-Optimizer. AdamW8bit von bitsandbytes (
optim="adamw_bnb_8bit") senkt die Optimizer-Zustände von 8 Bytes pro Parameter auf etwa 2. - LoRA oder QLoRA statt vollem Fine-Tuning. Sie trainieren kleine Adapter; QLoRA lädt das Basismodell in 4 Bit. Ein 8B-Modell trainiert mit QLoRA in 10–16 GB, ein 70B-Modell braucht etwa 48 GB und hat es mit 80 GB bequem.
- Kürzere Sequenzen oder niedrigere Auflösung. Für eine Flux-LoRA trainieren Sie zuerst mit 512–768 px und cachen Latents und Text-Embeddings.
- Mehrere Karten. FSDP oder DeepSpeed ZeRO verteilen Gewichte, Gradienten und Optimizer-Zustände auf mehrere GPUs.
Kommt der Absturz erst nach Hunderten von Schritten statt sofort, suchen Sie nach einem Leck: total_loss += loss hält den ganzen Graphen am Leben, total_loss += loss.item() nicht. Eine Evaluierung ohne torch.no_grad() bewirkt dasselbe.
Fragmentierung: PYTORCH_CUDA_ALLOC_CONF
Zeigt der Fehler Gigabytes als „reserved but unallocated“, ist der Speicher zwar da, aber in Stücke zerfallen, die für die Anforderung zu klein sind. Das passiert vor allem bei wechselnden Formen: unterschiedliche Bildgrößen, variierende Sequenzlängen oder Modelle, die abwechselnd geladen und entladen werden. Setzen Sie das, bevor Python startet:
export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
In einem Notebook schreiben Sie os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "expandable_segments:True" in die erste Zelle, vor import torch. Neuere PyTorch-Versionen lesen dieselbe Einstellung auch als PYTORCH_ALLOC_CONF. Bei älteren Versionen ist max_split_size_mb:128 die Alternative. Diese Einstellung schafft keinen Speicher; sie lässt Sie nur nutzen, was frei ist.
Um Ihren Job zu dimensionieren, messen Sie den Spitzenwert, statt zu raten: torch.cuda.max_memory_allocated() nach einem vollständigen Schritt oder einem Bild, und torch.cuda.memory_summary() für die Aufschlüsselung.
Wann Sie mit dem Tuning aufhören und eine größere Karte nehmen
Steigen Sie um, wenn die Lösung Sie Qualität kostet (von FP8 auf Q4), Tempo (CPU-Offload) oder mehr von Ihrer Zeit, als der Preisunterschied ausmacht. Zum Vergleich kostet eine Stunde ab 0,59 € auf einer RTX 4090 mit 24 GB, ab 0,76 € auf einer RTX 5090 mit 32 GB, ab 1,06 € auf einer L40S mit 48 GB und ab 3,90 € auf einer H100 mit 80 GB.
| Was immer wieder den Speicher sprengt | Kartengröße, die passt |
|---|---|
| Flux dev in 16 Bit oder Flux mit mehreren LoRAs und ControlNet | 24–32 GB |
| Wan 2.2 14B bei 720p ohne Offloading | 32 GB für kurze Clips, 48 GB mit Reserve |
| 32B-Modell mit 32.000+ Tokens Kontext oder mehreren Nutzern | 48–80 GB |
| 70B-Modell in 4 Bit | 48 GB bei normalem Kontext, 80 GB für langen Kontext oder den Betrieb als Dienst |
| 70B in FP8 | 80–96 GB bei kurzem Kontext, 141 GB oder zwei Karten für langen Kontext |
| Volles Fine-Tuning eines 7- bis 8B-Modells | Ab 80 GB oder mehrere Karten (QLoRA passt in 16–24 GB) |
Die VRAM-Auswahl zeigt, welche Karten zu Ihrem Modell passen und was sie gerade kosten; der Ratgeber wie viel VRAM Sie brauchen hat die vollständige Tabelle nach Modell. Ein kurzer Test auf der größeren Karte kostet nur 15 Minuten ihres Preises, und wenn Sie /workspace beim Stoppen speichern, wird der Ordner auf dem nächsten Server wiederhergestellt, auch wenn dieser eine andere Karte hat.