GPU-Runner für GitLab CI und GitHub Actions: eine Karte oder ein MIG-Slice pro Job
Eurokommerz, Wien, seit 2006: Private AI/ML · IT Managed Services · Enterprise Training · KI-Hardware & Software
- GitLab Runner gibt Jobs mit den Einstellungen gpus und service_gpus des Docker-Executors GPUs, im Format der Docker-CLI; der Kubernetes-Executor fordert nvidia.com/gpu über einen pod_spec-Patch an, hinter dem Feature-Flag FF_
USE_ ADVANCED_ POD_ SPEC_ CONFIGURATION - GitHub Actions führt GPU-Jobs auf selbst gehosteten Runnern aus; GitHub empfiehlt ephemere Runner, die sich nach einem Job abmelden, und warnt, selbst gehostete Runner „should almost never be used for public repositories“
- Ein registrierter Runner pro Karte mit limit = 1 hält Jobs auf getrennten GPUs; mit MIG bedient eine RTX PRO 6000 Blackwell Server Edition bis zu vier Jobs mit 24 GB, eine RTX PRO 4500 Server Edition zwei mit 16 GB
- Ein CI-Test auf einer L4 (Compute Capability 8.9) prüft nicht die sm_120-Codepfade, die RTX-PRO-Blackwell-Karten (12.0) im Betrieb ausführen
- Modellgewichte gehören in einen schreibgeschützten Cache, der mit HF_HUB_OFFLINE=1 in den Job eingebunden wird, nicht in einen neuen Download pro Job: Allein gpt-oss-120b umfasst etwa 65 GB Safetensors
Geliefert von Eurokommerz: RTX PRO 6000 und H200 NVL Preis und Verfügbarkeit anfragen →
Was ein GPU-Runner ist und wann ein Team ihn braucht
Ein GPU-Runner für CI ist ein selbst gehosteter GitLab Runner oder GitHub-Actions-Runner auf einem Rechner mit NVIDIA-Karte, NVIDIA-Treiber und NVIDIA Container Toolkit, so eingerichtet, dass jeder CI-Job eine GPU oder ein MIG-Slice erhält. Er übernimmt die Jobs, die ein normaler CPU-Runner nicht ausführen kann: CUDA-Unit-Tests, Kernel, kompiliert für die Karten im Produktivbetrieb, Modell-Evaluierungen gegen einen festen Testdatensatz und Smoke-Tests von Inferenz-Containern, bevor sie in Produktion gehen.
Teams kommen meist auf einem von drei Wegen an diesen Punkt. Eine CUDA- oder PyTorch-Codebasis bekommt Tests, die auf der CPU allein scheitern; ein ML-Team will bei jedem Merge Request die Evaluierung auf derselben Hardware wiederholen; oder ein Plattform-Team baut Inferenz-Images und will den Container mit einem echten Modell starten, bevor er in die Registry geht. In allen drei Fällen braucht der Job für einige Minuten exklusiven Zugriff auf bekannten GPU-Speicher, und der Runner muss so eingerichtet sein, dass nie zwei Jobs versehentlich auf derselben Karte landen.
Dieser Artikel behandelt die Runner-Seite: die Einstellungen, die GitLab und GitHub dokumentieren, Isolation pro Job, Caches, Sicherheit und die Karte. Wie Container grundsätzlich GPUs erhalten, steht in unserem Leitfaden zur GPU-Zuweisung in Docker ohne Kubernetes; GPUs zwischen Personen statt Pipelines aufzuteilen, ist Thema von GPU-Kosten verrechnen: Quoten je Abteilung.
GitLab Runner mit dem Docker-Executor und NVIDIA-GPUs
GitLabs Seite „Using Graphical Processing Units (GPUs)“ (Dokumentation zu GitLab Runner, Doku-Version 19.6, gelesen am 25. Oktober 2026) nennt GitLab Runner 13.9 als Einführung der GPU-Unterstützung und listet für den Docker-Executor die Voraussetzungen auf dem Host: den NVIDIA-Treiber und das NVIDIA Container Toolkit. Zwei Einstellungen im Abschnitt [runners.docker] erledigen die Arbeit: gpus für den Job-Container und service_gpus für Service-Container. GitLabs Beispiel setzt beide auf "all". Die Referenz zur erweiterten Konfiguration beschreibt beide als „GPU devices for Docker container. Uses the same format as the docker CLI.“
Dieses Format ist Dockers Option --gpus. Dockers Seite zum GPU-Zugriff zeigt --gpus all, --gpus device=0 für eine Karte nach Index, --gpus device=GPU-<uuid> für eine Karte nach UUID und '"device=0,2"' für zwei Karten, mit dem Hinweis „the device value must be quoted because it contains a comma.“ Der Shell-Executor braucht laut GitLab gar keine Runner-Konfiguration, gibt aber jedem Job den Host mit allen GPUs; GitLabs Sicherheitsseite rät, ihn „only for running trusted builds“ zu verwenden.
Die Einstellung gpus = "all" passt für einen Host, der jeweils einen GPU-Job ausführt. Auf einem Host mit vier Karten und vier parallelen Jobs ist sie falsch, weil jeder Job jede Karte sieht. GitLab bietet zwei Grenzen: den globalen Wert concurrent, der „limits how many jobs can run concurrently, across all registered runners“, und das limit pro Runner, das die Jobs begrenzt, die „concurrently by this registered runner“ laufen. Ein Runner-Eintrag pro Karte, jeder mit eigenem Gerät und einem Limit von eins, gibt jedem Job eine Karte:
| RUNNER-EINTRAG | GPUS-EINSTELLUNG | LIMIT |
|---|---|---|
| gpu-0 | gpus = "device=0" | 1 |
| gpu-1 | gpus = "device=1" | 1 |
| gpu-2 | gpus = "device=2" | 1 |
| gpu-3 | gpus = "device=3" | 1 |
unser Beispiel für einen Host mit vier Karten nach dem Docker-CLI-Format, das GitLab Runner für gpus dokumentiert (Doku 19.6), und der Gerätesyntax von Dockers Seite zum GPU-Zugriff; globales concurrent auf 4. Alles gelesen am 25. Oktober 2026.
GitLab schlägt vor, den Zugriff mit nvidia-smi am Anfang des Job-Skripts zu prüfen: Ist die GPU durchgereicht, listet der Befehl die Geräte, sonst scheitert er mit einem Fehler bei der Kommunikation mit dem Treiber. Behalten Sie diese Zeile im ersten Job jeder GPU-Pipeline. GitLab vermerkt außerdem eine Einschränkung: Mit Podman statt Docker wird die GPU nicht erkannt (GitLab-Issue 39095).
GitLab Runner unter Kubernetes
Mit dem Kubernetes-Executor ist die GPU eine Ressourcenanforderung. GitLabs Seite nennt zwei Voraussetzungen: einen Node Selector, der GPU-Knoten auswählt, und das Feature-Flag FF_. Das dokumentierte Beispiel ergänzt einen Eintrag [[runners.kubernetes.pod_ mit einem Strategic-Merge-Patch, der nvidia.com/gpu: 1 unter requests und limits des Containers build setzt. Laut GitLab wurde dies auf einem verwalteten Kubernetes-Dienst einer Public Cloud mit GPU-Instanzen getestet.
Der Ressourcenname stammt vom Device Plugin von NVIDIA, das der GPU Operator installiert. Mit MIG in der Strategie mixed wird jedes Profil zu einer eigenen Ressource, etwa nvidia.com/mig-1g.24gb für ein Viertel einer RTX PRO 6000, wie unser Artikel zu GPU-Sharing in Kubernetes mit MIG, Time-Slicing und MPS erklärt. Ein CI-Job fordert dann im selben Patch diesen Namen statt einer ganzen GPU an. Time-Slicing meldet eine Karte mehrfach an, ohne Speicherisolation, und widerspricht damit dem Ziel eines reproduzierbaren Tests; für CI würden wir ganze Karten oder MIG verwenden.
Selbst gehostete GPU-Runner für GitHub Actions
Von GitHub gehostete Runner sehen Ihre Hardware nicht; GPU-Jobs auf eigenen Karten laufen daher auf selbst gehosteten Runnern. GitHubs Dokumentation (gelesen am 25. Oktober 2026) sagt, ein solcher Runner „can be physical, virtual, in a container, on-premises, or in a cloud“, der Host „must be able to make outbound HTTPS connections over port 443“, und ein Job, der länger als 24 h in der Warteschlange steht, schlägt fehl. Jobs erreichen einen Runner über ihre Labels in runs-on; ein Label wie gpu-blackwell schickt einen Job zu den Karten, für die er geschrieben wurde.
Bei der Isolation ist GitHub deutlich. Es empfiehlt „autoscaling with ephemeral self-hosted runners“: Ein ephemerer Runner wird automatisch abgemeldet, „after it has processed one job“, und Just-in-Time-Runner entstehen über die REST-API für genau einen Job. GitHubs Sicherheitshinweise ergänzen, dass auch bei Runnern, die sich selbst entfernen, nicht sichergestellt ist, dass ein selbst gehosteter Runner nur einen Job ausführt, und dass Secrets, die als Kommandozeilenargumente übergeben werden, „can be seen by another job running on the same runner“; Just-in-Time-Runner „perform at most one job before being automatically removed“.
Unter Kubernetes ist der Actions Runner Controller (ARC) „the reference implementation of GitHub's scale set APIs“. GitHubs ARC-Seite hält fest: „You can fully customize the PodSpec of the runner pod“; eine GPU wird also wie bei jedem anderen Pod in den Ressourcen des Runner-Containers angefordert. Zwei Details zählen für GPUs. Im Docker-in-Docker-Modus „the Docker-in-Docker container requires privileged mode“, genau die Einstellung, die GitLabs Sicherheitsseite unsicher nennt. Im Modus kubernetes startet ARC Container-Jobs in einem neuen Pod im selben Namespace; prüfen Sie also, dass die GPU-Anforderung beim Pod ankommt, der den Job-Schritt ausführt, und nicht nur beim Runner-Pod. Die Werte minRunners und maxRunners begrenzen, wie viele GPU-Jobs gleichzeitig laufen; ohne beide skaliert ARC auf die Zahl der zugewiesenen Jobs.
Wir liefern L4, RTX PRO 4500 Server Edition und RTX PRO 6000 Server Edition, einzeln oder in Servern nach Maß; schicken Sie uns Ihre Pipelines und die Zahl paralleler GPU-Jobs, und unser Team antwortet mit einem Aufbau für den Runner-Host.
Eine GPU oder ein MIG-Slice pro Job
Die meisten CI-Jobs brauchen weit weniger als eine volle Karte mit 96 GB. MIG teilt eine Karte in Instanzen mit eigenem Speicher und eigenen Recheneinheiten, und NVIDIAs MIG User Guide (aktualisiert am 13. Oktober 2026) zeigt, wie ein Container eine davon auswählt: NVIDIA_ mit einer MIG-UUID oder Dockers --gpus '"device=0:0"' für das erste MIG-Gerät auf GPU 0, wobei „only one MIG device as chosen“ im Container sichtbar ist. Derselbe Wert lässt sich in die Einstellung gpus eines GitLab-Runner-Eintrags übernehmen, ein Eintrag pro Instanz. Mit nvidia-smi -L im Job prüfen Sie, welche Instanz er erhalten hat.
| KARTE | MIG PRO KARTE | SPEICHER PRO JOB |
|---|---|---|
| L4 | kein MIG | 24 GB, ganze Karte |
| RTX PRO 4000 Blackwell | kein MIG | 24 GB, ganze Karte |
| RTX PRO 4500 Server Edition | 2 Instanzen | 16 GB |
| RTX PRO 6000 Server Edition | bis zu 4 Instanzen | 24 GB (1g.24gb) |
| H200 NVL | bis zu 7 Instanzen | 18 GB (1g.18gb) |
NVIDIA MIG User Guide (Oktober 2026), zusammengefasst in unseren Artikeln zu RTX PRO 6000 MIG-Profilen und H200 NVL MIG-Profilen; Speichergrößen aus NVIDIA-Datenblättern.
Drei Grenzen gelten. Ein Job, der Multi-GPU-Code testet, etwa Tensor-Parallelismus über zwei Karten, braucht ganze Karten, weil ein Container ein MIG-Gerät sieht. MIG auf der RTX PRO 6000 setzt Linux, Treiber 575.51.03 oder neuer und die Karte im Compute-Display-Modus voraus; die Schritte stehen in unserer Anleitung zur MIG-Einrichtung. Und das MIG-Layout lässt sich nur ändern, solange kein Job auf der Karte läuft; wählen Sie also ein Layout für den Runner-Host und bleiben Sie dabei.
Sicherheit bei Merge Requests und Pull Requests
Ein CI-Runner führt Code von allen aus, die pushen oder einen Merge Request öffnen dürfen. GitLabs Sicherheitsseite sagt es direkt: „Any user that has the Developer role for the project's repository could compromise the security“ eines Runners, und „GitLab Runner is designed to run user-controlled scripts“. GitHub schreibt, selbst gehostete Runner „should almost never be used for public repositories on GitHub“, weil „any user can open pull requests against the repository and compromise the environment“.
Die dokumentierten Maßnahmen für einen GPU-Runner:
- Docker-Executor im nicht privilegierten Modus, den GitLab als sicher einstuft, und kein
privileged = trueoder--pid=hostauf dem GPU-Runner. Privilegierter Modus heißt laut GitLab „effectively disabling all the container's security mechanisms“. - Keine Pull Policy
if-not-presentauf Runnern, die Projekte mit unterschiedlichen Zugriffsrechten teilen; GitLab schließt sie aus, weil ein zwischengespeichertes Image zum Weg wird, Code in den Pipelines anderer Nutzer auszuführen. - Ephemere oder Just-in-Time-Runner bei GitHub, dort außerdem getrennte Runner-Sätze je Vertrauensstufe, beschränkt auf die Repositories, die sie nutzen dürfen.
- Ein eigenes Netzsegment für den Runner-Host, das GitLab vorschlägt, „to reduce the attack surface if a job is malicious“.
- Keine API-Schlüssel produktiver Modelle und keine Schreib-Tokens für die Registry auf dem GPU-Runner; Jobs, die Images veröffentlichen, laufen auf geschützten Branches, wie GitLab es für privilegierte Arbeit empfiehlt.
Treiber und Container Toolkit haben eigene CVEs. Die korrigierten Versionen je Zweig stehen in unserem Artikel GPU-Server absichern; ein CI-Host, der Code vieler Personen ausführt, sollte als erste Maschine gepatcht werden.
Modellgewichte und Caches zwischen Jobs
Ein Evaluierungsjob, der sein Modell jedes Mal vom Hub lädt, ist langsam und störanfällig. Die Files-Seite von gpt-oss-120b auf Hugging Face (gelesen am 25. Oktober 2026) listet im Hauptverzeichnis 15 Safetensors-Dateien mit zusammen etwa 65 GB und für das ganze Repository 196 GB, weil es auch die Ordner original/ und metal/ enthält. Bei 10 Gbit/s dauern allein die Dateien im Hauptverzeichnis nach unserer Schätzung mindestens 52 Sekunden, und jeder Job, der sie lädt, erhöht die Zahl der Anfragen, die gegen die Rate Limits des Hubs zählen.
Die Client-Bibliotheken von Hugging Face lesen den Cache-Ort aus HF_HUB_CACHE, Standard $HF_HOME/hub, und mit gesetztem HF_HUB_OFFLINE gilt „no HTTP calls will be made to the Hugging Face Hub“; es werden nur zwischengespeicherte Dateien verwendet (Referenz der Umgebungsvariablen von huggingface_hub, gelesen am 25. Oktober 2026). Auf einem GitLab Runner bindet die Einstellung volumes ein Host-Verzeichnis in Docker-Syntax -v ein, und environment setzt Variablen für den Job. Ein Cache, den ein vertrauenswürdiger Job einmal befüllt, lässt sich so schreibgeschützt in jeden GPU-Job einbinden, etwa /srv/hf:/hf:ro mit HF_ und HF_HUB_OFFLINE=1. Schreibschutz ist wichtig: In einem beschreibbaren gemeinsamen Cache kann ein Job Dateien ablegen, die spätere Jobs laden.
Wie der Cache über einen Firmen-Proxy mit festgelegten Revisionen und Prüfsummen befüllt wird, behandelt unser Artikel zu Hugging-Face-Modellen über Artifactory oder einen Proxy. Plattengrößen für Modellspeicher stehen in NVMe für LLM-Server.
Welche Karte für welche CI-Pipeline mit GPU
Die Karte im Runner sollte vor allem in einem Punkt der Karte im Betrieb entsprechen: in der Compute Capability. NVIDIAs Liste der CUDA-GPUs (gelesen am 25. Oktober 2026) nennt 8.9 für L4 und L40S, 9.0 für die H200 und 12.0 für jede RTX-PRO-Blackwell-Karte, Server Edition wie Workstation. Eine Testsuite, die auf einer L4 durchläuft, hat keinen einzigen sm_120-Kernel ausgeführt, und Builds ohne Blackwell-Code scheitern auf der Produktionskarte mit dem Fehler, den unser Artikel zu „no kernel image“ auf Blackwell (sm_120) behandelt.
| KARTE | COMPUTE CAP. | SPEICHER | LEISTUNG | ROLLE IN CI |
|---|---|---|---|---|
| L4 | 8.9 | 24 GB | 72 W | Tests für Ada- und L40S-Ziele |
| RTX PRO 4000 Blackwell | 12.0 | 24 GB | 145 W | Blackwell-Tests in einer Workstation |
| RTX PRO 4500 Server Edition | 12.0 | 32 GB | 165 W | Blackwell-Tests, 2 MIG-Jobs |
| RTX PRO 6000 Server Edition | 12.0 | 96 GB | bis 600 W | Evaluierung großer Modelle, 4 MIG-Jobs |
| H200 NVL | 9.0 | 141 GB | bis 600 W | Tests für Hopper-Ziele |
NVIDIA-Seite CUDA GPUs (Compute Capability) und NVIDIA-Datenblätter (Speicher, Leistung), gelesen im September und Oktober 2026.
Für ein Team, dessen Produktion auf Karten der RTX PRO 6000 Server Edition läuft, testet ein Runner-Host mit RTX PRO 4500 Server Edition dieselbe Architektur mit zwei Jobs pro Karte bei je 165 W, und eine RTX PRO 6000 Server Edition im selben Pool übernimmt die Evaluierungen, die ein großes Modell brauchen. Ein Team, das auf L4- oder L40S-Server ausliefert, testet auf einer L4: Low Profile, 72 W, und ihre 24 GB reichen für die meisten Unit-Tests. Die RTX PRO 4000 Blackwell ist eine Single-Slot-Workstation-Karte und passt eher in eine CI-Workstation im Labor als in einen Rack-Server.
Die Evaluierung eines Modells der 70B-Klasse ist eine andere Last. In FP8 belegen allein seine Gewichte nach unserem Sizing-Kanon 67,7 GiB; es braucht also eine ganze RTX PRO 6000 Server Edition oder eine H200 NVL, kein MIG-Slice. Wenn Sie für verschiedene Ziele bauen, nennen Sie uns die Architekturen, auf die Sie ausliefern, und wir schlagen einen Runner-Host mit einem Kartentyp pro Ziel vor.
Was wir liefern
Wir liefern L4, RTX PRO 4000, RTX PRO 4500 Server Edition, RTX PRO 6000 Server Edition und H200 NVL als Karten mit Herstellergarantie und bauen Workstations und KI-Server nach Maß, vor der Lieferung montiert und getestet, auf Wunsch mit Betriebssystem, NVIDIA-Treiber, CUDA und Container-Laufzeit, mit einem EU-Vertrag und einer Rechnung. Mengen und Lieferzeit werden schriftlich mit dem Angebot bestätigt.
FAQ
Wie nutze ich eine GPU in GitLab CI?
gpus (und service_gpus für Services) im Abschnitt [runners.docker] der config.toml, etwa auf „all“ oder „device=0“. Starten Sie den Job mit nvidia-smi, um zu prüfen, ob die GPU sichtbar ist. Unter Kubernetes fordern Sie nvidia.com/gpu über einen pod_spec-Patch an.Kann GitHub Actions auf einem selbst gehosteten Runner eine GPU nutzen?
runs-on dorthin. GitHub empfiehlt ephemere Runner, die einen Job ausführen, und rät von selbst gehosteten Runnern für öffentliche Repositories ab, weil jeder einen Pull Request öffnen kann.Wie bekommt jeder CI-Job seine eigene GPU?
gpus = "device=N" und limit = 1, und setzen Sie das globale concurrent auf die Zahl der Karten. Mit MIG gibt ein Eintrag pro MIG-Instanz jedem Job einen festen Speicheranteil.Welche GPU eignet sich für einen CI-Runner?
Ist es sicher, Merge Requests externer Beitragender auf einem GPU-Runner auszuführen?
Wie viele CI-Jobs kann eine RTX PRO 6000 Server Edition gleichzeitig ausführen?
Wir liefern L4, RTX PRO 4500 Server Edition und RTX PRO 6000 Server Edition und bauen Runner-Hosts mit installierten Treibern und Container Toolkit. Beschreiben Sie Ihre Aufgabe in wenigen Sätzen, unser Team hilft Ihnen weiter. Wir antworten innerhalb eines Werktages.
Mit einem Experten sprechenWir antworten innerhalb eines Werktages