VRAMfarm-Logo VRAMfarm
DE
Registrieren

12. November 2026 · VRAMfarm-Team

Multi-GPU-Training: DDP, FSDP und ZeRO auf einer gemieteten Maschine mit 2–8 GPUs

Vier GPUs in einem Server, verbunden durch Datenleitungen, mit darauf verteilten Modellteilen: Grundlagen des Multi-GPU-Trainings mit DDP, FSDP und ZeRO

Vier Karten gemietet, das Skript mit python train.py gestartet, und nvidia-smi zeigt eine Karte bei 100 % und drei bei 0 %. Kaputt ist nichts. Ein Trainingsskript nutzt eine GPU, solange es nicht über einen Launcher gestartet wird, der pro Karte einen Prozess startet, und die Arbeit muss so aufgeteilt werden, dass sie zu Ihrem Modell passt. Dafür gibt es zwei Wege: Jede Karte bekommt eine Kopie des Modells und einen Teil der Daten, oder das Modell selbst wird in Stücke geschnitten. Welchen Weg Sie brauchen, hängt davon ab, ob das Modell auf eine Karte passt.

Zuerst: Brauchen Sie überhaupt mehr als eine Karte?

Es gibt nur zwei Gründe für mehrere GPUs: Der Job passt nicht in den Speicher einer Karte, oder er dauert zu lange auf einer Karte. Bevor Sie zu einer Maschine mit mehreren GPUs greifen, prüfen Sie, ob eine einzelne größere Karte das Problem löst. Eine Karte ist immer einfacher: kein Launcher, keine Kommunikation zwischen Karten, keine NCCL-Fehler.

Job Eine Karte, die das schafft Wann mehrere Karten sinnvoll sind
LoRA oder QLoRA auf einem Modell bis 70B 24–80 GB, siehe den VRAM-Ratgeber Selten; um auf einem großen Datensatz schneller zu trainieren
Volles Fine-Tuning eines 7–8B-Modells Eine 80-GB-Karte mit 8-Bit-Optimizer oder eine H200 (141 GB) Für den Standard-Optimizer, längere Sequenzen oder einen kürzeren Lauf
Volles Fine-Tuning eines 13–70B-Modells Keine mit dem Standard-Optimizer; ein 13B-Modell passt nur mit 8-Bit-Optimizer auf eine Karte mit 141–192 GB Fast immer: 4–8 Karten mit FSDP oder ZeRO-3
Training eines kleinen Modells auf vielen Daten Jede Karte, auf die es passt Um einen Lauf von 40 Stunden auf 10 zu verkürzen
Betrieb eines 70B-Modells in fp8 H200 2 × H100 mit vLLM, siehe H200 oder H100

Die größten Einzelkarten im Katalog sind die B200 mit 192 GB, die H200 mit 141 GB und die RTX PRO 6000 mit 96 GB. Wenn eine davon Ihren Job fasst, fangen Sie dort an.

Datenparallelität: dasselbe Modell auf jeder Karte

Datenparalleles Training (PyTorch DDP) startet einen Prozess pro GPU. Jeder Prozess hält eine vollständige Kopie des Modells, nimmt einen anderen Teil jedes Batches, berechnet seine Gradienten, und dann mitteln alle Karten ihre Gradienten vor dem Optimizer-Schritt. Die Karten bleiben identisch, und N Karten verarbeiten pro Schritt N-mal so viele Daten.

Eine Voraussetzung gibt es: Modell, Gradienten, Optimizer-Zustände und Aktivierungen müssen auf eine Karte passen. Ist das so, ist DDP der einfachste Weg zu mehr Tempo. Sie starten das Skript mit einem Launcher statt mit python:

torchrun --nproc_per_node=4 train.py        # reines PyTorch, Hugging Face Trainer
accelerate launch --num_processes 4 train.py  # Hugging Face Accelerate

Der Hugging Face Trainer und die meisten Fine-Tuning-Werkzeuge (Axolotl, LLaMA-Factory, torchtune) schalten von selbst auf DDP um, wenn sie so gestartet werden. In reinem PyTorch verpacken Sie das Modell in DistributedDataParallel und fügen einen DistributedSampler hinzu.

Der Preis ist die Kommunikation: Nach jedem Schritt tauschen die Karten eine Kopie der Gradienten aus. Bei einem 1B-Modell in bf16 sind das etwa 2 GB pro Schritt, was PCIe schafft, während der Backward-Pass noch läuft. Rechnen Sie damit, dass zwei Karten etwa das 1,7- bis 1,9-Fache einer Karte leisten und vier Karten etwa das 3- bis 3,7-Fache, bei größeren Modellen auf Maschinen ohne NVLink weniger.

Wenn das Modell nicht passt: FSDP und DeepSpeed ZeRO

Mit dem üblichen AdamW-Optimizer in Mixed Precision kostet jeder Parameter rund 16 Bytes: 2 für die bf16-Gewichte, 2 für die Gradienten und 12 für den Optimizer (eine fp32-Masterkopie und zwei Momentschätzungen). Bei einem 8B-Modell sind das 128 GB vor den Aktivierungen, mehr als jede einzelne 80-GB-Karte.

Sharding teilt diese 16 Bytes auf die Karten auf, statt sie zu kopieren. DeepSpeed nennt das ZeRO und kennt drei Stufen; FSDP in PyTorch macht dasselbe unter anderen Namen. Für ein 8B-Modell:

Methode Was jede Karte hält Pro Karte, 4 Karten Pro Karte, 8 Karten
DDP Alles 128 GB 128 GB
ZeRO-1 Gewichte, Gradienten, 1/N des Optimizers 56 GB 44 GB
ZeRO-2, FSDP SHARD_GRAD_OP Gewichte, 1/N der Gradienten und des Optimizers 44 GB 30 GB
ZeRO-3, FSDP FULL_SHARD 1/N von allem 32 GB 16 GB

Die Aktivierungen kommen hinzu, je nach Sequenzlänge und Batch-Größe von wenigen GB bis zu Dutzenden GB pro Karte; Gradient Checkpointing verringert sie um den Preis von etwa einem Drittel mehr Rechenzeit. So lesen Sie die Tabelle: 4 Karten mit 80 GB schaffen ein volles Fine-Tuning eines 8B-Modells bequem mit ZeRO-2 oder ZeRO-3, 4 Karten mit 48 GB mit ZeRO-3, und 24-GB-Karten nur zu acht oder mit Auslagerung des Optimizers in den Arbeitsspeicher.

FSDP ist Teil von PyTorch; DeepSpeed wird mit einer JSON-Datei konfiguriert. Der Hugging Face Trainer und Accelerate unterstützen beides. CPU-Offload (ZeRO-Offload, FSDP cpu_offload) verschiebt die Optimizer-Zustände in den Arbeitsspeicher und lässt kleine Karten große Modelle trainieren, langsam und nur, wenn die Maschine genug RAM hat.

ZeRO-3 hat einen Preis, der auf gemieteten Maschinen zählt: Die Gewichte selbst wandern bei jedem Schritt zwischen den Karten hin und her. Bei einem 8B-Modell auf vier Karten sind das grob 35–50 GB pro Karte und Schritt. Über NVLink auf einer H100-Maschine dauert das einen Bruchteil einer Sekunde, über PCIe können es Sekunden sein, und die Karten warten. Deshalb ist die Art der Verbindung so wichtig.

Tensor- und Pipeline-Parallelität, und was die Inferenz nutzt

Tensor-Parallelität schneidet jede Gewichtsmatrix in Scheiben, eine pro Karte, und tauscht in jeder Schicht Daten aus. Sie funktioniert deshalb nur über NVLink gut. Pipeline-Parallelität legt verschiedene Schichten auf verschiedene Karten, mit weniger Datenverkehr, aber mit Karten, die warten, während sich die Pipeline füllt. Frameworks fürs Pre-Training wie Megatron kombinieren beides; fürs Fine-Tuning reicht meist FSDP oder ZeRO.

Bei der Inferenz ist es einfacher. vLLM teilt ein Modell mit --tensor-parallel-size 2 (oder 4, 8) auf, llama.cpp und Ollama verteilen die Schichten von selbst auf die Karten. Inferenz schickt wenig Daten zwischen den Karten hin und her und läuft deshalb auch über PCIe ordentlich.

Eine Falle: device_map="auto" in Hugging Face Transformers verteilt die Schichten auf die Karten und führt sie nacheinander aus. Das Modell passt, aber es arbeitet immer nur eine Karte. Zum Ausprobieren eines großen Modells ist das in Ordnung, für schnelles Training nicht.

Verbindung Geschwindigkeit zwischen Karten, ungefähr Wo Sie sie finden
PCIe 4.0 x16 25–32 GB/s pro Richtung RTX 3090, RTX 4090, A6000, die meisten PCIe-Karten
PCIe 5.0 x16 50–64 GB/s pro Richtung RTX 5090, RTX PRO 6000, neuere Server
NVLink-Brücke, RTX 3090 etwa 112 GB/s Auf gemieteten Maschinen selten
NVLink, A100 SXM 600 GB/s A100-SXM-Boards mit 4 und 8 Karten
NVLink, H100 / H200 SXM 900 GB/s SXM-Boards mit 4 und 8 Karten

Consumer-Karten haben eine weitere Grenze: Die RTX 4090 unterstützt keine direkten Peer-to-Peer-Übertragungen, Daten zwischen den Karten laufen also über den Arbeitsspeicher. Maschinen mit mehreren 4090 eignen sich gut für Inferenz und für DDP mit kleinen Modellen, schlecht für ZeRO-3 mit großen.

Der Katalog zeigt den Kartennamen vor dem Start. „SXM“ oder „SXM4“ bedeutet, dass die Karten auf einem Board für NVLink sitzen; PCIe-Karten haben vielleicht Brücken, vielleicht nicht. Der Filter „PCIe“ im Katalog gibt die Busgeschwindigkeit zwischen CPU und GPUs an. Sie zählt beim Laden von Daten und Modellen (eine Karte in einem schmalen x4-Steckplatz lädt langsam), sagt aber nichts über die Verbindung zwischen den Karten. Dafür führen Sie gleich nach dem Start Folgendes aus:

nvidia-smi topo -m

NV4, NV12 oder NV18 zwischen zwei Karten bedeutet NVLink. PIX und PXB stehen für einen PCIe-Switch, PHB für die PCIe-Brücke der CPU, und NODE oder SYS für einen Weg quer über die CPU, den langsamsten.

Eine Maschine mit mehreren GPUs bei VRAMfarm mieten

  1. Maschine auswählen. Stellen Sie im Serverkatalog „Karten pro Maschine“ auf 2×, 4× oder 8×. Der Preis gilt pro Stunde für die ganze Maschine, etwa die Zahl der Karten mal der Preis einer Karte: ab 2,36 € pro Stunde für 4 × RTX 4090, ab 31,20 € für 8 × H100. Jede Zeile zeigt Kartenname, CPU-Kerne, RAM, Festplatte, Treiber, CUDA-Version und Land.
  2. Die Filter nutzen, die fürs Training zählen. VRAM pro Maschine, RAM (mindestens der gesamte VRAM), CPU-Kerne (4–8 pro Karte), freie Festplatte (ein vollständiger Checkpoint eines 8B-Modells mit Optimizer-Zuständen hat über 100 GB) und „Mietdauer“, also wie viele Tage am Stück die Maschine gehalten werden kann. Lassen Sie bei langen Läufen Reserve.
  3. Einen leeren Server wählen. PyTorch mit Jupyter oder Ihr eigenes Docker-Image. Um zu starten, muss Ihr Guthaben eine Stunde der ganzen Maschine abdecken; das ist eine Prüfung, keine Abbuchung, abgerechnet wird minutengenau.
  4. Die Maschine in den ersten Minuten prüfen. Führen Sie nvidia-smi, nvidia-smi topo -m und python -c "import torch; print(torch.cuda.device_count())" aus. Stimmt etwas nicht, stoppen Sie den Server: Sie zahlen das Minimum von 15 Minuten, nicht die Stunde.
  5. Vor dem eigentlichen Job einen kurzen Kommunikationstest laufen lassen:
# nccl_check.py: starten mit  torchrun --nproc_per_node=4 nccl_check.py
import os, time, torch, torch.distributed as dist
rank = int(os.environ["LOCAL_RANK"]); torch.cuda.set_device(rank)
dist.init_process_group("nccl")
x = torch.ones(512 * 1024**2, dtype=torch.bfloat16, device="cuda")  # 1 GiB
for _ in range(3): dist.all_reduce(x)
torch.cuda.synchronize(); t = time.time()
for _ in range(10): dist.all_reduce(x)
torch.cuda.synchronize()
if rank == 0: print(f"{10 / (time.time() - t):.1f} all-reduces of 1 GiB per second")
dist.destroy_process_group()

Gibt er eine Zahl aus, sprechen die Karten miteinander; eine NVLink-Maschine sollte um ein Vielfaches schneller sein als eine mit PCIe. Hängt er, lesen Sie die erste Stolperfalle unten.

Die API nimmt die Zahl der Karten als count entgegen. Ein Skript kann also für einen Nachtlauf eine Maschine mit 8 Karten starten und sie stoppen, wenn der Job fertig ist.

Häufige Stolperfallen

  • NCCL hängt oder meldet „unhandled system error“. Starten Sie mit NCCL_DEBUG=INFO, um zu sehen, wo es stehen bleibt. Auf Consumer-Karten behebt NCCL_P2P_DISABLE=1 Hänger oft. Ist ein Prozess abgestürzt, warten die anderen bis zum Timeout auf ihn; suchen Sie im Log also den ersten Fehler, nicht den letzten.
  • Zu wenig Shared Memory. In Containern hat /dev/shm manchmal nur ein paar Dutzend Megabyte, und dann brechen NCCL und Data Loader mit „bus error“ ab. Prüfen Sie das mit df -h /dev/shm; senken Sie num_workers, oder versuchen Sie NCCL_SHM_DISABLE=1.
  • Die Batch-Größe hat sich unbemerkt geändert. Globaler Batch = Batch pro Karte × Zahl der Karten × Schritte der Gradientenakkumulation. Wechseln Sie mit derselben Konfiguration von 1 auf 4 Karten, wird der Batch viermal so groß und die Epoche in Schritten viermal so kurz. Senken Sie entweder die Akkumulationsschritte, um den globalen Batch zu halten, oder erhöhen Sie die Lernrate: bei SGD ungefähr linear, bei Adam vorsichtiger (mit der Quadratwurzel), mit Warm-up.
  • Jede Karte sieht dieselben Daten. Ohne DistributedSampler trainieren alle Karten auf identischen Batches; ohne sampler.set_epoch(epoch) hat jede Epoche dieselbe Reihenfolge. Der Hugging Face Trainer kümmert sich um beides.
  • Vier Kopien jedes Logs und Checkpoints. Schreiben Sie Dateien nur auf Rank 0. Ein vollständiger FSDP-Checkpoint wird im Arbeitsspeicher eines einzigen Prozesses zusammengesetzt; Sharded Checkpoints vermeiden das.
  • „System not yet initialized“ auf einer SXM-Maschine mit 8 Karten. Das kommt vom NVLink-Fabric des Anbieters, nicht aus Ihrem Code. Stoppen Sie den Server, wählen Sie eine andere Maschine und sagen Sie dem Support Bescheid.

Lange Läufe brauchen zwei Gewohnheiten. Starten Sie das Training in tmux, damit es einen zugeklappten Laptop übersteht. Speichern Sie alle 30–60 Minuten Checkpoints in /workspace, behalten Sie nur die letzten zwei, und kopieren Sie sie bei Läufen über einen Tag von der Maschine: Die Serverfestplatte wird beim Stoppen gelöscht, wenn Sie den Ordner nicht speichern (was mit Ihren Dateien passiert). Solange die GPUs beschäftigt sind, lässt die Leerlauferkennung den Server in Ruhe. Endet der Lauf, beginnt sie zu zählen: Nach 2 Stunden ohne GPU-Last, SSH- oder Jupyter-Verbindung bekommen Sie eine E-Mail, eine Stunde später wird der Ordner gespeichert und der Server stoppt. Sie können das abschalten, und Server mit Ihrem eigenen Docker-Image werden nicht automatisch gestoppt. Günstiger ist eine letzte Zeile in Ihrem Skript, die den Server über die API stoppt.

Beginnen Sie mit zwei Karten und einem kurzen Lauf, messen Sie die Zeit pro Schritt und skalieren Sie dann auf vier oder acht. Sind zwei Karten nicht annähernd doppelt so schnell wie eine, helfen auch mehr Karten nicht; sehen Sie sich zuerst die Verbindung zwischen ihnen an.

Fragen zum Thema

Kann ich verschiedene GPUs in einer Maschine mischen?

Nein. Jede Maschine im Katalog hat Karten eines einzigen Modells, angezeigt zum Beispiel als „4× RTX 4090“. Das ist auch, was Sie wollen: Beim datenparallelen Training wartet bei jedem Schritt jede Karte auf die langsamste.

Nutzen ComfyUI oder Ollama alle Karten?

Ollama, llama.cpp und vLLM können ein Sprachmodell auf mehrere Karten verteilen. ComfyUI führt einen Workflow auf einer Karte aus. Auf einer Maschine mit 4 GPUs starten Sie also vier ComfyUI-Instanzen, jede mit CUDA_VISIBLE_DEVICES auf ihrer eigenen Karte, um vier Batches parallel zu rendern.

Wie viele CPU-Kerne und wie viel RAM brauche ich pro GPU?

Als Faustregel 4–8 CPU-Kerne pro GPU, damit das Laden der Daten mithält, und mindestens so viel Arbeitsspeicher wie der gesamte VRAM der Maschine. CPU-Offload in DeepSpeed oder FSDP braucht deutlich mehr: Allein das Auslagern des Optimizers eines 8B-Modells belegt rund 100 GB RAM.

Was passiert mit meinem Lauf, wenn die Maschine ausfällt?

Die Abrechnung endet ab dem Moment, in dem die Maschine weg war, und Sie bekommen eine Benachrichtigung, aber die Festplatte des Servers ist mit ihr verloren. Kopieren Sie bei Läufen über ein paar Stunden regelmäßig Checkpoints von der Maschine, zum Beispiel in ein privates Hugging-Face-Repository oder Ihren eigenen S3-Bucket.

Finden Sie die GPU, auf die Ihr Modell passt

Wählen Sie ein Modell und sehen Sie die günstigste Karte mit genug VRAM, minutengenau in Euro abgerechnet.