Plánovanie úloh v AI klastroch: SLURM, Kubernetes, Ray a kedy nepotrebujete ani jeden z nich

Plánovač rozhoduje, ktorá úloha pobeží na ktorých GPU, kedy a na čí účet. Bez neho sa zdieľaný klaster zvrhne na to, že si ľudia na Slacku navzájom píšu, či niekto náhodou nepoužíva uzol 3. S nesprávnym plánovačom strávite viac inžinierskych hodín nad YAML-om než nad samotnými modelmi.

Tento článok porovnáva plánovače, ktoré si ľudia reálne vyberajú — SLURM, Kubernetes (s Kueue alebo Volcano), Ray a KubeRay a komerčné riešenia Run:ai a Determined — a férovo priznáva aj prípad, keď je správnou odpoveďou „nič, stačí SSH“. Čitateľ už má za sebou K01, K02 a K03 a teraz sa rozhoduje, čo postaviť nad klaster s 1–32 uzlami.

Čo plánovač vlastne robí

Tri úlohy, zhruba podľa náročnosti: umiestniť prácu na voľné zdroje, zaradiť do fronty prácu, ktorá sa zatiaľ nezmestí, a koordinovať viacuzlové úlohy — distribuovaný tréning potrebuje, aby sa všetkých N rankov spustilo naraz (gang scheduling), pretože PyTorch dist.barrier() blokuje donekonečna, ak sa jeden rank nikdy neobjaví (pozri K06).

Čokoľvek nad rámec klastra pre jeden tím navyše potrebuje multi-tenant kvóty s požičiavaním, útlm fair-share naprieč tímami, preempciu a poriadne účtovanie GPU (aby úloha videla správne nastavenú premennú CUDA_VISIBLE_DEVICES). Prvé tri veci zvládne každý plánovač nižšie. Rozchádzajú sa až v druhom zozname a v tom, aký typ práce predpokladajú.

Hlavné delenie: dávkové úlohy verzus dlhobežiace služby

Toto je zďaleka najdôležitejšie rozlíšenie. Dávkové úlohy trénujú 8 hodín a skončia, prebehnú hyperparametrický sweep s 200 krátkymi úlohami alebo cez noc spracujú dataset — začiatok, koniec, výsledok, nič neodpovedá na HTTP. Dlhobežiace služby sú vLLM endpoint obsluhujúci inferenciu 24/7, databáza scene-memory či monitorovací stack — majú bežať stále a po páde sa reštartovať.

SLURM vznikol pre dávky. Kubernetes vzniklo pre dlhobežiace služby. Všetko ostatné je jedno z tých dvoch, naťahované tak, aby zvládlo aj druhú polovicu.

Workload SLURM Kubernetes
8-hodinový tréningový beh Natívne Potrebuje Kueue alebo Volcano
Hyperparametrický sweep s 200 úlohami Natívne Nemotorné
Inferenčný endpoint vLLM 24/7 Nemotorné Natívne
Zmiešané: tréning + inferencia + nástroje Bolestivé Natívne (s Kueue)
Viacuzlový distribuovaný tréning Natívne (gang) Potrebuje gang plugin
Automatický reštart spadnutých služieb Nie Natívne

Ak váš klaster robí len jednu z týchto vecí, voľba je jednoduchá. Ak robí oboje — čo je čoraz bežnejšie — otázka znie, pri ktorom plánovači ste ochotní zaplatiť prevádzkovú daň.

SLURM — predvoľba zo sveta HPC, ktorá pri čistom tréningu stále vyhráva

Na SLURM beží viac než 65 % superpočítačov z rebríčka TOP500 a väčšina publikovaných frontier tréningov. Pre workloady typu „odošlite tréningovú úlohu, počkajte na výsledky, prevezmite checkpoint“ je správnou odpoveďou už dvadsať rokov.

Mentálny model je jednoduchý: partícia je pomenovaný pool uzlov (gpu-5090, cpu-only, bigmem); úloha je shell skript s direktívami #SBATCH, odoslaný príkazom sbatch; GRES (Generic RESources) eviduje GPU — --gres=gpu:rtxpro6000:2 si vyžiada dve konkrétne karty; gang scheduling je zabudovaný.

Minimálny slurm.conf pre 4-uzlový klaster s 8× RTX Pro 6000 Blackwell na uzol:

ClusterName=kentino-lab
SlurmctldHost=head01

SchedulerType=sched/backfill
SelectType=select/cons_tres
SelectTypeParameters=CR_Core_Memory
GresTypes=gpu

# Účtovanie GPU — bez týchto dvoch riadkov beží fair-share na CPU-sekundách a nemá zmysel
AccountingStorageType=accounting_storage/slurmdbd
AccountingStorageTRES=gres/gpu
PriorityType=priority/multifactor
PriorityDecayHalfLife=7-0
PriorityWeightFairshare=10000
PriorityWeightAge=1000

# cgroups izolujú GPU, ktoré úloha smie vidieť
ProctrackType=proctrack/cgroup

NodeName=node[01-04] CPUs=128 RealMemory=1024000 Sockets=2 \
    CoresPerSocket=64 ThreadsPerCore=1 Gres=gpu:rtxpro6000:8 State=UNKNOWN

PartitionName=train Nodes=node[01-03] Default=YES MaxTime=48:00:00 State=UP
PartitionName=interactive Nodes=node04 MaxTime=04:00:00 \
    PriorityTier=10 State=UP

Zodpovedajúci gres.conf na každom uzle:

AutoDetect=nvml
NodeName=node[01-04] Name=gpu Type=rtxpro6000 File=/dev/nvidia[0-7]

AutoDetect=nvml sa pýta priamo knižnice NVIDIA Management Library, automaticky zachytí aj MIG slice a ušetrí vám ručné písanie ciest k súborom zariadení.

Používateľ odošle:

#!/bin/bash
#SBATCH --job-name=qwen-finetune
#SBATCH --partition=train
#SBATCH --nodes=2
#SBATCH --ntasks-per-node=8
#SBATCH --gres=gpu:rtxpro6000:8
#SBATCH --time=12:00:00
#SBATCH --output=logs/%j.out

srun python -m torch.distributed.run \
    --nnodes=2 --nproc-per-node=8 \
    --rdzv-backend=c10d \
    --rdzv-endpoint=$(scontrol show hostnames | head -1):29500 \
    train.py --config configs/qwen72b.yaml

PyTorch Elastic a SLURM do seba zapadajú čisto: SLURM vlastní alokáciu, srun spustí jeden proces na úlohu a torch.distributed.run spolu s rendezvous backendom rieši priradenie rankov. Pri výpadku uzla sa vďaka --max-restarts v torchrun a --requeue v #SBATCH beh obnoví z posledného checkpointu. Takto to robí každý.

Čo dostanete zadarmo: gang scheduling, útlm fair-share, backfill, účtovanie (každá GPU-sekunda zapísaná do sacct) a jednoduchú sémantiku — žiadne CRD, žiadny controller, žiadny graf YAML objektov. Čo nedostanete: dlhobežiace služby s automatickým reštartom, HTTP ingress, rolling updates, sidecar kontajnery, deklaratívny stav. SLURM je dávkový plánovač. Ak s ním budete zaobchádzať ako s Kubernetes, zabolí to.

SLURM je správna voľba, keď: prevádzkujete tréning, dávkovú inferenciu alebo simulácie; používatelia píšu shell skripty; klaster zvládne obsluhovať jeden SRE na čiastočný úväzok.

Kde SLURM naráža na strop

Na troch miestach. Služby webového typu — neexistuje tu pojem „bež stále, po páde sa reštartuj, vystav port 8000“. vLLM síce do dlhobežiacej SLURM úlohy natlačíte, ale health-check, rolling updates a load balancing sa stanú vaším problémom. Heterogénne workloady — SLURM predpokladá jeden pool zdrojov; klaster, na ktorom beží tréning + inferencia + Jupyter + monitoring + príprava dát, potrebuje jemnejšie nastavenie. Prísna multi-tenant izolácia — cgroups izolujú CPU a pamäť; izolácia GPU stojí na CUDA_VISIBLE_DEVICES a na tom, že ju kód používateľa rešpektuje. Žiadne namespaces, žiadne sieťové politiky na úrovni úlohy, žiadna tenancia na úrovni kontajnerov. Pre laboratóriá to stačí, pre hostovanú službu s viacerými zákazníkmi nie.

Keď na čokoľvek z toho narazíte, správnym krokom je zvyčajne pridať druhú vrstvu — Kubernetes pre služby — a nie trápiť SLURM. CoreWeave so svojím SUNK a manažované ponuky roku 2026 prevádzkujú SLURM na Kubernetes, takže ten istý klaster zvládne oboje. V mierke Kentino bývajú jednoduchšie dva samostatné malé klastre.

Kubernetes pre AI: cloud-native cesta

Kubernetes vzniklo preto, aby udržalo v chode bezstavové webové služby. Pre AI klastre sa „všetko ostatné“ priskrutkuje zvonku. Stack roku 2026: NVIDIA GPU Operator (ovládače, CUDA, NCCL, DCGM, device plugin, konfigurácia MIG), Kueue (fronta, kvóty, admission), Volcano (plánovač so znalosťou dávok), Kubeflow Trainer (CRD PyTorchJob, TFJob, MPIJob), KubeRay (Ray na K8s) a Karpenter alebo Cluster Autoscaler na provisioning uzlov.

Prečo je naivný Kubernetes pre AI nesprávny: predvolený kube-scheduler je FIFO bez gang sémantiky. Pokojne spustí 7 z 8 podov distribuovaného tréningu a ôsmy nechá v stave Pending, zatiaľ čo bežiaca sedmička drží GPU naprázdno. Nie je to teoretický problém — je to najčastejšia chyba tímov, ktoré sa pokúsia spustiť tréning na klastri postavenom pre inferenciu. Riešením sú Kueue (admission na úrovni úlohy) a Volcano (gang umiestnenie na úrovni podov). Súčasná najlepšia prax je oboje: Kueue navrchu, Volcano pod ním.

Volcano

Volcano je dávkový plánovač z CNCF, ktorý sa inštaluje popri kube-scheduleri alebo namiesto neho. Pridáva skutočný gang scheduling so sémantikou minAvailable (prijme nula alebo N, nikdy nie časť), priority a preempciu front, stratégie fair-share / binpack / topology-aware a prvotriednu podporu pre PyTorchJob, TFJob, MPIJob, RayJob a SparkApplication.

Minimálna fronta a gang-plánovaná tréningová úloha PyTorch:

apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
  name: training
spec:
  weight: 4
  capability:
    nvidia.com/gpu: 32
---
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
  name: qwen-finetune
spec:
  schedulerName: volcano
  minAvailable: 16          # gang: všetkých 16 rankov alebo nič
  queue: training
  policies:
    - event: PodEvicted
      action: RestartJob
  tasks:
    - replicas: 16
      name: worker
      template:
        spec:
          containers:
            - name: pytorch
              image: kentino/pytorch:2.5-cuda13
              resources:
                limits:
                  nvidia.com/gpu: 1
              command: ["torchrun", "--nnodes=16", "--nproc-per-node=1", "train.py"]

Kedy Volcano nepotrebujete: pri čisto inferenčnom klastri s nezávislými vLLM Deploymentmi. Každý pod vlastní svoje GPU, žiadna koordinácia medzi podmi, predvolený kube-scheduler stačí. Volcano sa začne vyplácať vo chvíli, keď do klastra pridáte distribuovaný tréning.

Kueue a požičiavanie kvót

Kueue rieši vrstvu, ktorú Volcano nerieši: kto smie spotrebovať akú časť klastra a čo sa stane, keď je jeden tím nečinný.

apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
  name: rtxpro6000
spec:
  nodeLabels:
    nvidia.com/gpu.product: "RTX-PRO-6000-Blackwell"
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
  name: team-research
spec:
  cohort: "shared-gpu"
  resourceGroups:
    - coveredResources: ["nvidia.com/gpu"]
      flavors:
        - name: rtxpro6000
          resources:
            - name: "nvidia.com/gpu"
              nominalQuota: 16
              borrowingLimit: 8

Oba tímy v kohorte majú garantovaných 16 GPU a z nečinného poolu toho druhého si môžu požičať až 8. Práca s vysokou prioritou požičanú kapacitu preempuje. Roadmapa Kueue na rok 2026 sa sústredí na MultiKueue (dispatch naprieč klastrami) a kooperatívnu preempciu — úlohe, ktorá si robí checkpointy, možno povedať „ulož stav a do 60 sekúnd uvoľni miesto“ namiesto toho, aby bola rovno zabitá.

MIG a zdieľanie GPU

Device plugin od NVIDIA predvolene prideľuje celé GPU. Pre tréning a veľkú inferenciu je to správne, pre malú inferenciu, notebooky či vývoj je to plytvanie. Tri režimy zdieľania: MIG (hardvérová izolácia pamäte a chýb, produkčná multi-tenant inferencia), MPS (kooperatívny, bez izolácie), time-slicing (bez izolácie, len na vývoj).

MIG existuje na H100/H200, A100 a B200 — na žiadnom GPU z portfólia Kentino nie. RTX 5090, RTX 4090, RTX Pro 6000 Blackwell, L40 ani L4 MIG nepodporujú. Ak váš návrh vyžaduje hardvérovo izolované partície GPU, obmedzuje vás to na SXM/datacentrové diely, ktoré Kentino nestavia. Time-slicing ohlási N virtuálnych GPU na jedno fyzické a plánovač netuší, že sú preplnené — používajte ho len pri vývoji.

V čom je Kubernetes dobrý: dlhobežiace inferenčné služby (vLLM Deploymenty škálované cez HPA podľa hĺbky fronty, rolling updates, health checks — SLURM nemá nič porovnateľné), heterogénne workloady na jednom klastri, ekosystém (Prometheus, Grafana, Argo). Čo za to zaplatíte: funkčný stack K8s + GPU Operator + Kueue + Volcano + Kubeflow má minimálne 20 komponentov. Realistický odhad: Kubernetes znamená 5–10× väčšiu prevádzkovú záťaž než SLURM pri čistom dávkovom tréningu.

Kubernetes je správna voľba, keď: na klastri bežia inferenčné služby popri tréningu, máte platformový tím, záleží vám na deklaratívnosti všetkého alebo potrebujete prenositeľnosť medzi klastrami.

Ray a KubeRay — distribuovaný výpočet natívne v Pythone

Ray je iné zviera. Nie je to naozaj klastrový plánovač v zmysle SLURM či K8s — je to distribuovaný Python runtime, ktorý so sebou nesie plánovač, object store a autoscaler. Píšete Python s dekorátormi @ray.remote a Ray si sám určí, kde ktorú úlohu spustí.

Kam sa Ray hodí: ladenie hyperparametrov (Ray Tune — stovky pokusov paralelne so skorým orezaním tých zlých; prípad použitia, pre ktorý Ray vznikol a v ktorom je stále najlepší), posilňované učenie (RLlib — prostredia a learnery ako aktéri, čo na Ray sadne čisto a na dávkové úlohy SLURM zle), distribuovaný tréning (Ray Train obaľujúci PyTorch DDP / FSDP / DeepSpeed), serving modelov (Ray Serve, natívne v Pythone, vlastné viacmodelové pipeline) a predspracovanie dát (Ray Data). Čím Ray nie je: multi-tenant dávkovým plánovačom pre zdieľaný klaster. Ray predpokladá, že klaster vlastní jedna aplikácia.

KubeRay je operátor, ktorý prevádzkuje Ray na Kubernetes. Tri CRD: RayCluster (dlhožijúci), RayJob (jednorazový), RayService (Ray Serve, rolling updates). Minimálny RayCluster:

apiVersion: ray.io/v1
kind: RayCluster
metadata:
  name: rl-cluster
spec:
  rayVersion: '2.55.0'
  headGroupSpec:
    rayStartParams: { dashboard-host: '0.0.0.0' }
    template:
      spec:
        containers:
          - name: ray-head
            image: rayproject/ray:2.55.0-py311-cu125
            resources:
              limits: { cpu: 8, memory: 32Gi }
  workerGroupSpecs:
    - groupName: gpu-workers
      replicas: 4
      minReplicas: 0
      maxReplicas: 8
      rayStartParams: {}
      template:
        spec:
          containers:
            - name: ray-worker
              image: rayproject/ray:2.55.0-py311-cu125
              resources:
                limits:
                  cpu: 16
                  memory: 128Gi
                  nvidia.com/gpu: 4

KubeRay škáluje skupinu workerov medzi minReplicas a maxReplicas podľa toho, ako Ray vidí čakajúce úlohy. V kombinácii s Kueue (RayJob + gang scheduling cez Kueue je zdokumentovaný a funguje) dostanete multi-tenant Ray na multi-tenant K8s klastri — produkčné nasadenie, aké reálne prevádzkuje väčšina „Ray firiem“.

Kedy je samostatný Ray (bez K8s) na mieste: v malom výskumnom laboratóriu, kde klaster vlastní jeden človek, kde je dynamika dôležitejšia než multi-tenancia a kde workload stojí najmä na RL alebo hľadaní hyperparametrov. Hybrid, ku ktorému väčšina tímov dospeje: SLURM alebo K8s ako základná vrstva, ktorá vlastní uzly a multi-tenanciu; Ray spustený vo vnútri SLURM úlohy alebo K8s namespace na čas workloadu jedného používateľa. Neinštalujte Ray ako svoj najvyšší plánovač.

Run:ai a Determined — komerčná vrstva

Dve platené riešenia sa skloňujú dosť často na to, aby sme ich spomenuli. Obe mieria na rovnaké bolestivé miesto: K8s + Volcano + Kueue + GPU Operator je veľa YAML-u a niektoré organizácie radšej kúpia, než stavajú.

NVIDIA Run:ai (akvizícia 2024, rebranding 2025) je plánovač GPU natívny pre K8s. Frakcionovanie GPU rozdelí jedno GPU medzi workloady na úrovni pamäte — požiadavky typu 0.5 GPU, dynamická zmena veľkosti, bin-packing. Run:ai sa oplatí v podnikových prostrediach s 10+ ML tímami, ktoré súperia o zdieľané GPU. Pod touto hranicou pokryje väčšinu toho istého Kueue + GPU Operator zadarmo.

Determined.AI (HPE, 2021) je manažovaná tréningová platforma — sledovanie experimentov, hľadanie hyperparametrov, správa checkpointov a distribuovaný tréning v jednom produkte. Najlepšie sadne výskumným tímom, ktoré chcú vyladený dashboard bez toho, aby si samy integrovali päť nástrojov.

Problém interaktívnych notebookov

Vzorec, ktorý dobehne takmer každý zdieľaný GPU klaster: výskumníci chcú na vývoj prístup k GPU cez JupyterHub a to musí koexistovať s dlhobežiacimi tréningovými úlohami, ktoré držia celé uzly. Naivná odpoveď — jedno vyhradené GPU na notebook — premrhá 80 % klastra. Prísna odpoveď — nech výskumníci všetko posielajú cez sbatch — ich vytlačí na notebooky s hračkárskymi modelmi.

Tri použiteľné vzorce: SLURM salloc + Jupyter na alokácii (salloc --gres=gpu:1 --time=4:00:00, na pridelenom uzle spustíte Jupyter server a pripojíte sa tunelom; tvrdý časový limit, GPU riadne zaúčtované — najčistejšia odpoveď pre SLURM klaster), Kubernetes + JupyterHub + Kueue (pody s notebookmi cez frontu s nízkou prioritou, tréningové úlohy nečinné notebooky preempujú), prípadne Run:ai s frakcionovaním GPU (každý notebook dostane 0.25 / 0.5 GPU). Nech si vyberiete čokoľvek, nastavte interaktívnym reláciám časový limit — notebook bez timeoutu je GPU natrvalo vyradené z klastra.

Úprimná realita malých tímov

Väčšina online obsahu o plánovačoch predpokladá klaster s 256 GPU a platformový tím. Reálny zákazník Kentino je bližšie k 1–4 uzlom, celkovo 4–32 GPU a 2–6 používateľom, ktorí sa navzájom poznajú a dohodnú sa na Slacku. Pre takú zostavu plánovač nepotrebujete.

# používateľ 1
ssh node01
tmux new -s my-training
CUDA_VISIBLE_DEVICES=0,1,2,3 python train.py
# Ctrl-B D na odpojenie

# používateľ 2 — najprv sa dohodne na Slacku
ssh node01
nvidia-smi                              # ktoré GPU sú voľné?
tmux new -s other-training
CUDA_VISIBLE_DEVICES=4,5,6,7 python train.py

To je celý systém plánovania úloh. SLURM sa začína vyplácať zhruba pri 16 GPU alebo 8 používateľoch, podľa toho, čo príde skôr. Pod touto hranicou prevádzková réžia prevýši prínos. Plánovač nasaďte vtedy, keď zlyháva ľudská koordinácia, nie skôr.

Kam ktorý nástroj patrí — zhrnutie

Scenár Odporúčanie
1–2 uzly, 4–16 GPU, 2–6 používateľov, ktorí spolu komunikujú SSH + tmux + nvidia-smi. Žiadny plánovač.
Výskumné laboratórium, 4–32 uzlov, dávkové tréningové úlohy SLURM. Nudný, overený, sadne.
Inferenčná platforma obsluhujúca zákaznícku prevádzku Kubernetes + GPU Operator. Bez dávkového plánovača.
Zmiešaný klaster: tréning + inferencia + nástroje Kubernetes + Kueue + Volcano + Kubeflow.
Náročný distribuovaný Python: RL, hľadanie hyperparametrov Ray (alebo KubeRay) nad SLURM či K8s.
10+ ML tímov súperiacich o GPU, rozpočet na nástroje Run:ai na Kubernetes.
Manažované tréningové experimenty + sledovanie Determined.AI.
200+ GPU, viac tímov, viac workloadov Federovane: SLURM na dávky, K8s na služby.

Čo ďalej — rozhodovací strom

Prechádzajte to po poradí. Prvé „áno“ diskusiu ukončí.

  1. Menej ako 16 GPU a menej ako 8 používateľov, ktorí spolu komunikujú? Áno → žiadny plánovač. Dohodnuté pravidlá zapíšte do markdown súboru. Vráťte sa k tomu, keď koordinácia prestane fungovať.
  2. Bežia na klastri popri tréningu aj dlhobežiace inferenčné služby? Áno → základom je Kubernetes. Pridajte GPU Operator, potom Kueue a potom Volcano, ak je v hre distribuovaný tréning. Nie → základom je SLURM.
  3. Máte platformový tím alebo rozpočet naň (0.5–1.0 FTE na šesť mesiacov, 0.25 FTE v ustálenom stave)? Nie → zostaňte na SLURM bez ohľadu na mix workloadov. Daň za K8s je reálna.
  4. >10 tímov súperiacich o čas na GPU s prísnymi nárokmi na kvóty? Áno → zvážte Run:ai. Nie → Kueue + kohorty vás dostanú na 80 % cesty.
  5. Stojí workload najmä na RL, hľadaní hyperparametrov alebo distribuovanom Pythone? Áno → Ray (KubeRay na K8s alebo salloc + Ray na SLURM). Nie → Ray vynechajte.
  6. Podporuje hardvér MIG (datacentrové karty)? Pri portfóliu Kentino nie → počítajte s pridelením celého GPU alebo s time-slicingom len vo vývoji. Nenavrhujte riešenie okolo MIG.

Väčšina rozhovorov v Kentino sa končí pri kroku 1, 2 alebo 3. Zvyšok je dekorácia.

Súvisiace články: distribuovaný tréning v K02, inferenčné klastre v K03, úložisko klastra v K04, riešenie porúch v K06, strop priepustnosti PCIe v K07.


Toto je súčasť Kentino Wiki, referenčnej série o AI výpočtoch, robotike a systémoch, ktoré ich spájajú. Pripomienky a opravy vítame na adrese info@kentino.com.