Vigilant Inference Governor

NV-12: CUDA-Graphs bringen 4 % und kosten den Mehrmodellbetrieb

Datum: 10.09.2026. Maschine: RTX 3070 Laptop (8 GB), Treiber 580.173.02, Triton 2.70.0 (26.06-py3), TensorRT-Engines aus demselben ONNX wie der Gate-M3-Lauf.

Kein eigener Codepfad

CUDA-Graphs sind über Tritons Modellkonfiguration erreichbar:

optimization {
  cuda { graphs: true }
}

Damit ist NV-12 dasselbe wie NV-08 bei TensorRT — eine Messfrage, kein Arbeitspaket am Governor. Der Governor sieht davon nichts; er misst, was das Backend liefert.

Was es bringt

pose_main allein in einem Triton-Server, drei Läufe zu je 300 Messungen, periodisch freigegeben alle 40 ms:

Lauf 1 Lauf 2 Lauf 3 Median
ohne Graphs, p50 5184 us 5224 us 5203 us 5203 us
mit Graphs, p50 5009 us 5006 us 5159 us 5009 us
ohne Graphs, p95 5759 us 5612 us 5640 us 5640 us
mit Graphs, p95 5462 us 5485 us 5563 us 5485 us

3,7 % weniger p50, 2,7 % weniger p95. Die Streuung zwischen Läufen derselben Konfiguration liegt bei rund 1 %, der Unterschied also knapp, aber über dem Rauschen.

Das ist die erwartete Größenordnung: CUDA-Graphs sparen Kernel-Launch-Overhead, und der ist bei einem 5-ms-Kernelbündel klein gegenüber der Rechenzeit. Bei einem Modell aus vielen sehr kurzen Kerneln wäre mehr zu erwarten.

Was es kostet

Den Mehrmodellbetrieb. Und das ist die Prämisse dieses Produkts.

Ein Modell mit graphs: true lädt. Mehrere nicht:

rfdetr:     UNAVAILABLE: Internal: unable to create TensorRT engine:
            IRuntime::deserializeCudaEngine: Error Code 1: Cuda Runtime
            (In syncStreams at resources.cpp:407)
depth_main: UNAVAILABLE: dasselbe
pose_main:  unable to record CUDA graph for pose_main_0_0
            unable to finish CUDA graph: operation failed due to a previous
            error during capture

Triton lädt Modelle nebenläufig. Die Graph-Aufnahme des einen macht den Legacy-Stream für den anderen unbrauchbar, und das trifft auch Modelle, die gar keine Graphs eingeschaltet haben:

vlm_main: CUDA failure 906: operation would make the legacy stream depend on
          a capturing blocking stream
          (onnxruntime gpu_data_transfer.cc, cudaStreamSynchronize(nullptr))

vlm_main läuft auf onnxruntime und hatte graphs nach dem ersten Befund ausdrücklich abgeschaltet. Es scheiterte trotzdem — an der Aufnahme eines anderen Modells.

Reproduziert und eingegrenzt:

Aufbau Ergebnis
vier Modelle, alle mit Graphs zwei Modelle laden nicht
drei TensorRT-Modelle, alle mit Graphs eines lädt nicht
ein TensorRT-Modell mit Graphs lädt

Der erste Start des Vier-Modell-Aufbaus gelang; der zweite nicht. Es ist ein Wettlauf beim Laden, kein deterministischer Fehler — was ihn für den Betrieb schlechter macht, nicht besser.

Das Urteil

Für einen Governor, dessen ganzer Zweck es ist, mehrere Modelle auf einer Karte zu ordnen, sind CUDA-Graphs auf diesem Stack nicht einsetzbar. 4 % Laufzeit gegen einen nichtdeterministischen Ladefehler ist kein Tausch.

Was das nicht heißt: dass CUDA-Graphs nichts taugen. Auf einem neueren Treiber (das Image verlangt 610.43, hier läuft 580.173.02), mit graph_spec-Einträgen statt der pauschalen Aufnahme oder mit sequenziellem Modell-Laden kann das anders aussehen. Gemessen ist der Stack, der hier steht.

Ein eigener TensorRT-Direktpfad (NV-09) hätte die Kontrolle über die Aufnahmereihenfolge und damit über genau diesen Fehler. Er braucht die unsafe-Entscheidung, die in STATUS steht.