Ohne Kategorie

Zwei GPUs machten mein 120B-Modell 5x langsamer – und schuld war ein PCIe-Steckplatz

Ich habe einem Mixture-of-Experts-Modell mit 120 Milliarden Parametern eine zweite GPU gegeben. Es wurde fünfmal langsamer. Hier die Messung — und der nützlichere Fund, den ich nebenbei gemacht habe.

Der Aufbau

Zwei RTX 3090 in einem Rechner. Kein NVLink — die Karten reden ausschließlich über PCIe 3.0 miteinander. Das Modell ist gpt-oss-120b, MXFP4 quantisiert, viel zu groß für eine einzelne 24-GB-Karte. Die Engine hält die Experten im Host-RAM und schiebt sie bei Bedarf auf die GPU. Diese Last steht und fällt also mit der Busbandbreite.

Eine Karte gegen zwei

Gleiche Sitzung, gleiche Prompts, beide Karten sonst frei:

255 Token 799 Token
1 GPU 16,0 tok/s 25,8 tok/s
2 GPUs (Tensor-Parallel) 4,6 tok/s 5,0 tok/s
−71 % −81 %

Technisch lief es einwandfrei. Beide Karten wurden bestückt (je rund 21 GB), die Antworten kamen vollständig. Tensor-Parallelität teilt jede Schicht auf beide GPUs auf — das bedeutet einen All-Reduce bei jedem Durchlauf. Über PCIe 3.0 ohne NVLink kostet dieser Verkehr mehr, als die zweite Karte einbringt. Zwei Karten sind hier nicht „mehr GPU“. Sie sind eine GPU plus Steuer.

Der Zufallsfund, der mehr wert ist als das Experiment

Am selben Tag hatte ich den Einzelkarten-Fall zuvor mit 8,3 und 10,0 tok/s gemessen — etwa die Hälfte der Werte oben. An der Software hatte sich nichts geändert. Geändert hatte sich, auf welcher Karte der Job landete.

Einer meiner beiden Steckplätze läuft mit x8, der andere mit x16. Solange nur die x8-Karte sichtbar war, nahm der Job sie. Waren beide sichtbar, wählte die Engine die x16-Karte. Gleiches Modell, gleicher Code, Faktor 2,6.

Für alles, was Gewichte über den Bus nachschiebt statt sie resident zu halten, ist der Steckplatz keine Nebensache. Wer einen schnellen und einen langsamen hat, sollte wissen, welcher welcher ist.

Zwei Arten, wie ich mich selbst getäuscht habe

Die Engine konnte die CUDA-Kollektive nicht bauen — und das traf auch den Einzelkarten-Fall. Fehlendes NCCL zeigte sich als Linker-Fehler, aber erst, nachdem ich die zweite Karte sichtbar gemacht hatte. Der Einzelkarten-Lauf hatte nur funktioniert, weil die andere Karte verborgen war. Wer die GPU-Sichtbarkeit ändert, ändert den Codepfad, nicht nur die Kapazität.

Mein Bereitschaftstest hat gelogen. Ich fragte /v1/models ab, und das antwortet lange mit 200, bevor die Gewichte geladen sind. Der Server sah nach 13 Sekunden bereit aus, und ich notierte drei „Messwerte“, die allesamt HTTP 503 waren. Ehrlich ist eine echte Vervollständigung als Sonde, bei der 503 „noch nicht“ heißt. Tatsächliche Ladezeit dieses Modells: rund zehn Minuten.

Was ich mitnehme

Das Interessante ist nicht, dass Tensor-Parallelität ohne NVLink langsam ist — das war zu erwarten. Interessant ist, wie viel meines Tages in zwei Messfehler geflossen ist, von denen jeder exakt wie ein echter Befund aussah. Eine Zahl, deren Herkunft man nicht geprüft hat, ist keine Messung. Sie ist ein Gerücht mit Nachkommastelle.