In den ersten drei Beiträgen dieser kleinen Serie habe ich erklärt, warum ich mir TensorRT-LLM auf der A6000 Ada vornehme (Teil 1), wie ich das Setup mit Docker und Helper-Skripten aufgebaut habe (Teil 2), und welche Build-Pipeline für FP16 und FP8 dahintersteckt (Teil 3). Jetzt zum spannendsten Teil: Die echten Zahlen und was sich daraus für den Transfer auf Edge-LLM lernen lässt.
Was ich hier zeige, sind keine synthetischen Benchmarks aus einer Marketing-Folie, sondern Messwerte aus meinem eigenen Setup: Qwen2.5-7B-Instruct, RTX 6000 Ada Generation (SM89), Ubuntu 24.04, TensorRT-LLM 1.2.1 im NGC-Container. Die Generation-Tokens/sec sind mit gleichen Prompts und gleichen Sampling-Parametern gemessen, sodass FP16 und FP8 direkt vergleichbar sind.
Die Vergleichstabelle
| Metrik | FP16 TensorRT | FP8 TensorRT | Delta |
|---|---|---|---|
| Build-Pipeline | |||
| Quantize/Convert | 2:00 (120s) | 7:34 (454s) | +278 % |
| Engine-Build | 2:46 (166s) | 3:56 (236s) | +42 % |
| Gesamt | 4:46 (286s) | 11:30 (690s) | +141 % |
| Artefakte | |||
| TRT-LLM Checkpoint | 15 GB | 8,2 GB | −45 % |
| TensorRT Engine | 15 GB | 8,2 GB | −45 % |
| Runtime | |||
| Engine-Load | 33,24 s | 18,04 s | −46 % (1,84×) |
| Generation-Zeit (3 Prompts) | 2,50 s | 1,53 s | −39 % |
| Tokens/sec (batched) | 153,72 | 251,15 | +63 % (1,63×) |
| Output-Quality | ✓ | ✓ | gleich |
Die wichtigste Zahl steht in der vorletzten Zeile: +63 % Throughput bei 45 % kleinerer Engine. Das ist exakt in dem Bereich, den NVIDIA für FP8 auf Ada bewirbt und mit dem ich vor diesem Experiment nur theoretisch hätte argumentieren können.
Die eigentliche Erkenntnis: Welche Zahlen sind belastbar?
Beim Wiederholen des Experiments und das habe ich wirklich oft gemacht bis alles so lief wie ich wollte, also dem erfolgreichen Durchspielen meiner eigenen Build-Skripte über mehrere Sessions hinweg habe ich Folgendes festgestellt: Die Build-Zeiten schwanken erheblich, während die Inference-Performance bemerkenswert reproduzierbar bleibt.
Beispiel aus zwei meiner Sessions:
| Metrik | Session A | Session B | Differenz |
|---|---|---|---|
| FP16 Gesamt-Build | 9:10 | 4:46 | nahezu halbiert |
| FP8 Gesamt-Build | 5:54 | 11:30 | nahezu verdoppelt |
| FP16 Tokens/sec | 154,00 | 153,72 | ±0,2 % |
| FP8 Tokens/sec | 250,04 | 251,15 | ±0,4 % |
Die Erklärung steckt in der Natur der jeweiligen Operationen. Build-Zeit ist I/O-dominiert und hier habe ich einen etwas betagten Rechner und SSD. Also das Schreiben einer 15-GB-Engine-Datei hängt vom Disk-Cache-Zustand, anderen laufenden Prozessen, ggf. Power-Management der SSD ab. Inference ist Compute-dominiert die GPU rechnet bei gleicher Engine und gleichen Prompts deterministisch, weitgehend unabhängig vom System-Zustand drumherum wenn das Modell einmal in den VRAM der GPU geladen ist.
Daraus folgt ein praktischer Hinweis: Inference-Benchmarks sind belastbar, Build-Zeit-Vergleiche brauchen mehr Vorsicht aber wenn ein Modell gut läuft baut man es ja nicht ständig neu. Das der Build-Prozess in der benötigten Zeit schwankt ist meiner Meinung nach nicht so schlimm.
Engine-Load: Faktor 1,84× durch kleinere Datei
Bei der Engine-Lade-Zeit zahlt die kleinere FP8-Datei direkt ein. FP16-Engine-Load auf meinem Setup: 33,24 Sekunden. FP8-Engine-Load: 18,04 Sekunden. Faktor 1,84×. Das ist natürlich wichtig wenn wir jetzt nicht an eine RTX A6000 GPU in einer Workstation denken sondern an ein Edge Gerät das nach dem Einschalten so schnell wie möglich z. B. den Sprachassistenten hochgefahren haben muss wie es eben möglich ist.
Wenn ich mit jetzt die Ladezeiten im Detail anschaue. Dann entfallen davon bei beiden ein konstanter Anteil auf die KV-Cache-Allokation und MPI-Worker-Initialisierung, der unabhängig von der Engine-Größe ist. Der Rest ist reines Lesen der .engine-Datei in den ich saghe jetzt einfach VRAM da die Werte von meiner GPU stammen und hier schrumpft mit der Engine-Größe die Ladezeit. Bei FP8 ist die Datei nur etwa die Hälfte so groß, also halbiert sich genau dieser Teil.
Für mich persönlich ist Engine-Load-Zeit selten kritisch. Denn ich starte die Engine einmal beim Container-Start. Aber für Anwendungen, wo der Service-Cold-Start zählt z. B. ein Cloud-Worker, der auf Anfrage hochfährt ist das ein realer Vorteil oder wenn Modelle regelmäßig gewechselt werden müssen.
Tokens/sec: Wo der eigentliche FP8-Gewinn zu finden ist
Ob 251 Tokens/sec viel oder wenig sind, hängt vom Vergleich ab — und der Vergleich ist trickreich. Auf derselben A6000 Ada habe ich auch Ollama in zwei Quantisierungs-Stufen gemessen, um die Effekte von Compilation und Quantisierung sauber zu trennen:
| Engine | Quantisierung | Tokens/sec |
|---|---|---|
| Ollama FP16 | 16 bit | 60 |
| TRT-LLM FP16 | 16 bit | 154 |
| Ollama Q4_K_M | 4 bit | 168 |
| TRT-LLM FP8 | 8 bit | 251 |
Daraus lassen sich drei Effekte sauber trennen:
Bei gleicher Bit-Breite gewinnt TRT-LLM klar. FP16 gegen FP16 ist das ein Faktor von 2,5× — der reine Vorteil einer hardware-spezifischen, kompilierten Pipeline gegenüber einer portablen llama.cpp-Implementierung mit generischen Dispatch-Pfaden. Das ist der eigentliche „Compilation-Win“, der gerne als pauschales „TRT-LLM ist schneller“ beworben wird.
Aggressive Quantisierung gewinnt unterproportional Memory-Bandbreite zurück. Ollama gewinnt mit Q4_K_M Faktor 2,8× gegenüber seinem eigenen FP16, TRT-LLM gewinnt mit FP8 dagegen nur Faktor 1,6× gegenüber seinem FP16. Das liegt nicht daran, dass FP8 schlechter quantisiert — die TRT-LLM-FP16-Baseline ist einfach schon viel höher.
Die eigentliche Überraschung steckt im realistischen User-Vergleich. Wer naiv „TRT-LLM mit FP16″ gegen „Ollama mit Default-Quantisierung“ stellt, vergleicht 154 tok/s gegen 168 tok/s — und Ollama gewinnt. Die 4-bit-Quantisierung holt im Decode-Loop mehr Performance zurück, als die Compilation einbringt. Erst mit TRT-LLM FP8 zieht das kompilierte Backend wieder davon — Faktor 1,5× gegenüber Ollama Q4. Das ist deutlich weniger als die gerne behaupteten „3× schneller als Ollama“, aber immer noch ein klarer Vorsprung.
Wo TRT-LLM seine ganze Stärke ausspielt, ist die Kombination: FP8-Quantisierung plus Hardware-FP8-Tensorkerne. Gegenüber einem unquantisierten Ollama FP16 ist das Faktor 4,2×. Aber ohne das Hardware-FP8-Feature der Ada-Generation (oder Hopper, Blackwell, Jetson Thor) würde TRT-LLM gegen ein gut quantisiertes llama.cpp-Modell auf vielen Use Cases nicht mehr gewinnen. Das macht die Wahl der Hardware mindestens so entscheidend wie die Wahl des Inferenz-Backends.
Die Lektion, die nicht in der Doku steht: KV-Cache-Quantisierung
Ich habe in Teil 3 schon davon erzählt, will sie hier aber als zentrale Lehre nochmal festhalten: Mein erster FP8-Build hatte zusätzlich --kv_cache_dtype fp8 gesetzt. Die Performance-Zahlen waren noch besser (236 statt 251 tok/s), aber das Modell produzierte kompletten Token-Salat:
strugg (str, 1, 1, 1, 1, 1, 1, 1) 1) 1) 1) 1) 1) 1) 1) 1) 1) ...
Auf alle drei Prompts dasselbe Phänomen. Die Engine lief perfekt — KV-Cache-Allokation, Tensorkern-Auslastung, Throughput, alle Metriken sahen super aus. Nur eines wurde nicht gemessen: Output-Quality.
Die Diagnose: Bei 7B-Modellen ist die FP8-Quantisierung des KV-Cache zu aggressiv. Der Quality-Headroom dieser kleineren Modelle reicht nicht aus, um sowohl Weights als auch Aktivierungen im KV-Cache nach FP8 zu komprimieren. Bei 70B+ Modellen — die typischerweise mehr Redundanz und damit mehr Robustheit haben — kann FP8-KV-Cache funktionieren.
Der Fix war eine einzige Konfigurations-Änderung: Statt --kv_cache_dtype fp8 lasse ich die Option ganz weg. Der KV-Cache bleibt dann bei nativem FP16. Output wird wieder sinnvoll, die anderen Performance-Vorteile von FP8-Weights bleiben erhalten.
Generelle Lehre, die ich aus dieser Sitzung mitnehme: Quantisierungs-Performance ohne Quality-Verifikation ist wertlos. Ein Benchmark-Skript hätte den Bug nie gefunden — die Engine generierte ja Tokens, und zwar schneller als die Variante ohne FP8-KV. Erst das Lesen der eigentlichen Outputs offenbarte den Collapse.
Das gilt für jede Quantisierung, nicht nur FP8: INT8, INT4-AWQ, NF4 – alle haben einen Quality/Performance-Trade-off. Und wie der Ollama-Vergleich oben gezeigt hat, sind auch die Cross-Engine-Vergleiche nicht so einfach wie „kompiliertes Backend gewinnt automatisch“. Wer Inferenz produktiv betreibt, braucht zwingend ein Quality-Sample im CI/CD und eine ehrliche Sicht auf die Baseline gegen die verglichen wird — nicht nur Latenz-Messungen aus einer Session.
Was davon ist auf Edge-LLM übertragbar?
Zurück zum eigentlichen Ziel dieser Serie. Was habe ich gelernt, das ich später direkt auf Jetson Thor (oder ein anderes Edge-Target) mitnehmen kann?
Direkt übertragbar
- Die Pipeline-Konzepte: HF → ONNX/TRT-LLM-Checkpoint → TensorRT Engine. Bei Edge-LLM heißt die Mittelstufe ONNX statt TRT-LLM-Checkpoint, aber die Trennung von Convert/Quantize und Build ist identisch.
- Der Build-Once-Deploy-Many-Pattern: Engine wird auf einer Workstation gebaut, dann als statisches Artefakt deployt. Edge-LLM ist explizit nur für dieses Pattern designt — die High-Level-Python-API mit on-the-fly Engine-Build, wie sie TRT-LLM hat, gibt es bei Edge-LLM gar nicht.
- Das Verständnis der Build-Bottlenecks: Kernel-Auto-Tuning vs. Disk-I/O. Auf Edge-Targets mit limitierter Disk-Performance wird die Serialisierung relativ noch wichtiger.
- Die FP8-Quantisierung mit ModelOpt. Funktioniert auf SM89 (Ada) und auf den entsprechenden Jetson-Varianten gleich.
- Die KV-Cache-Lehre ist universell. Genauso relevant auf Edge.
- Der Methodik-Hinweis: Inference-Benchmarks sind belastbar, Build-Zeit-Vergleiche brauchen mehrere Durchläufe. Das wird beim Vergleich von Edge-Konfigurationen genauso wichtig sein.
Neu lernen müsste ich
- C++-only Runtime. Edge-LLM hat keinen Python-Layer. Wer dort eine Engine ausführen will, schreibt eine C++-Anwendung gegen die LLM-Runtime-API. Für meine bisherigen Tests habe ich immer Python genutzt — auf Edge ist das nicht verfügbar.
- Statisches Memory-Layout statt Paged KV-Cache. Edge-LLM verzichtet auf dynamische Allokation, weil die Workloads vorhersagbar sind. Andere Tuning-Knöpfe.
- Cross-Compile-Tooling. Engines für Jetson Thor (SM101, aarch64) baut man typischerweise auf einem x86-Host und deployt die fertige
.engine-Datei auf das Edge-Gerät. Bei TRT-LLM auf meiner Ada baue ich nativ — selbe Architektur, Container, Build und Run auf derselben Maschine.
Was komplett anders gedacht werden muss
- Hardware-FP8-Verfügbarkeit auf dem Edge-Target. Jetson Thor bringt Hardware-FP8 mit (gleiche Architektur-Klasse wie Ada/Hopper). Auf älteren Edge-Plattformen wie Jetson Orin gibt es das nicht. Das bedeutet natürlich das dort der Vorteil gegenüber einem gut quantisierten llama.cpp-Modell zusammen, wie der Ollama-Vergleich oben angedeutet hat wegschmilzt. Wer Edge-LLM-Performance plant, muss daher zuerst klären, welche Architektur-Generation die Zielhardware ist.
- Power/Thermal-Budget. Auf der A6000 Ada kann ich 300 Watt verheizen. Auf einem Jetson Thor sind das vielleicht 60 Watt unter Volllast, oft 30 Watt sustained. Die Quantisierungs-Wahl ist dann nicht mehr nur Performance vs. Quality, sondern auch Performance pro Watt.
- Modell-Größe. Was auf der A6000 Ada locker passt (Qwen-7B in FP8: 8 GB), passt auf einem Jetson Thor mit 128 GB Shared Memory zwar prinzipiell auch — aber dort konkurriert die Modell-Engine mit Vision-Pipelines, dem OS, anderen Tasks. Realistische Modellgrößen sind eher 1B–14B.
Fazit: War es das wert?
Mehrere Tage Arbeit, vier Blog-Posts. Was habe ich am Ende für meine LLM-Projekte gelernt?
Konkret auf der Festplatte
- Eine FP16- und eine FP8-Engine für Qwen-7B, beide als
.engine-Datei deploybar - Sieben Build- und Run-Skripte, die den kompletten Workflow reproduzierbar machen
- Messwerte mit allen relevanten Metriken
- Eine Stolperfallen-Sammlung, die ich nicht zwei Mal lernen muss
Mental
- Ein wirklich konkretes Verständnis von dem, was zwischen einem HuggingFace-Repo und einem effizienten Edge-Deployment passiert
- Eine ehrliche Einschätzung von FP8 als Quantisierungs-Verfahren das nicht nur „1,63× schneller“ ist, sondern auch „pass auf den KV-Cache auf“ und „Build-Zeit-Vergleiche kritisch betrachten“ wenn das ein Thema sein sollte
- Eine Roadmap, was ich später für Edge-LLM noch dazu lernen muss (C++ Runtime, Cross-Compile, statisches Memory-Modell)
Für mich war das die richtige Investition. Edge-AI auf souveräner Hardware ist nicht mehr „demnächst“ die Werkzeuge sind da, die Architektur-Konzepte sind klar, und mit jedem Schritt wird die Distanz zwischen meiner Workstation und einem Jetson Thor kleiner. Wer in dem Feld arbeitet oder dazu lernen will, kann sich diese Übung mit jeder Ada-GPU oder neueren Karte selbst zum eigen machen.
Jetzt schaue ich mal in meiner Werkstatt was ich noch an Edge-Geräten habe. Ein alter Jetson Nano sollte noch zu finden sein.
Artikelübersicht - TensorRT-LLM auf der RTX A6000 Ada:
Ubuntu 24.04 Server für KI-Inferenz vorbereiten: CUDA, Docker, NVIDIA Container ToolkitTensorRT-LLM auf der RTX A6000 Ada: Vorbereitung auf das Edge-LLM Ökosystem
TensorRT-LLM auf Ubuntu 24.04: Setup mit Docker und Helper-Skripten
TensorRT-LLM Pipeline: Persistente Engines bauen mit FP16 und FP8
TensorRT-LLM in Zahlen: FP16 vs. FP8 auf der RTX A6000 Ada








Ein toller Guide der leicht zugänglich und verständlich ist. Perfekt für ein kleines Side-Project geeignet. Aktuell half mir noch mein…
Thank you for this great tutorial, could you share n8n workflow and comfyui workflow please?
Hallo Anton, die Meldung besagt das in meinem Beisiel Methoden verwendet werden die veraltet (deprecated) sind. Also müsstest Du die…
Danke für das Tool! Ich habe erst kürzlich angefangen mich mit der Thematik zu beschäftigen und bin für meine Erwartungen…
Hallo, ich habe ihre Anleitung befolgt und bekomme im letzten Schritt leider immer folgende Meldung im Terminal: bash <(wget -qO-…