GRESでGPUを定義する
一言でいうと
SlurmではGPUは、GRES(Generic RESource)という汎用的なデバイスリソースとして扱われます。2つのファイルが互いに一致している必要があります。slurm.confとgres.confです。
なぜ必要なのか
CPUとメモリは、Slurmが自分で数えられます。しかしGPUは? FPGAは? NVMeは? Slurmはこうしたものを直接は知らないので、管理者が宣言する仕組みを作りました。それがGRESです。
どう動くのか
2つのファイルの役割
| ファイル | 何を書くか | 配布範囲 |
|---|---|---|
slurm.conf |
どのGRESタイプが存在し、各ノードにいくつあるか | すべてのノードで同一 |
gres.conf |
そのGRESが実際にどのデバイスファイルに対応するか | ノードごとに異なってよい |
slurm.conf側:
GresTypes=gpu
NodeName=gpu-node01 ... Gres=gpu:a100:4 State=UNKNOWN
gres.conf側:
NodeName=gpu-node01 Name=gpu Type=a100 File=/dev/nvidia[0-3] Cores=0-15
両者の数は必ず一致している必要があります。slurm.confにgpu:a100:8と書いたのに、gres.confがFile=/dev/nvidia[0-3]だと4個しかありません。この場合、slurmdがログにgres/gpu count reported lower than configuredを残して、ノードをDRAINにします。最もよくあるGRES設定ミスです。
CoresとNUMAアフィニティ
NodeName=gpu-node01 Name=gpu Type=a100 File=/dev/nvidia0 Cores=0-15
NodeName=gpu-node01 Name=gpu Type=a100 File=/dev/nvidia1 Cores=0-15
NodeName=gpu-node01 Name=gpu Type=a100 File=/dev/nvidia2 Cores=16-31
NodeName=gpu-node01 Name=gpu Type=a100 File=/dev/nvidia3 Cores=16-31
Cores=は、そのGPUと物理的に近い(同じNUMAノードに接続された)CPUコアを教えます。Slurmはこの情報でGPUとCPUを同じソケットに配置し、PCIeの往復を減らします。大規模な学習では、この差が数パーセントになります。
実際のトポロジーは、nvidia-smi topo -mで確認します。
AutoDetect
AutoDetect=nvml
NVMLライブラリでGPUを自動検出します。デバイスファイルとNUMAアフィニティを自動で埋めてくれるので楽ですが、NVMLがインストールされていて、SlurmもNVMLとともにビルドされている必要があります。そして、自動検出の結果がslurm.confの宣言と違えば、やはりノードは外れます。自動が検証まで代わりにやってくれるわけではありません。
手動での定義は面倒ですが、明示的で再現可能です。エアギャップ環境や異種混在のクラスターでは、手動のほうが安全な場合が多くあります。
MIG
A100/H100のMIGを使うと、物理GPU1枚が複数のインスタンスに分割されます。このときは、各MIGインスタンスが別々のGRESの項目になり、Type=にプロファイル名が入ります。
NodeName=gpu-node01 Name=gpu Type=1g.10gb File=/dev/nvidia-caps/...
MIG構成が変わったら、gres.confも一緒に変える必要があります。これを自動化しないと、MIGを再構成するたびにノードが外れます。
GPUの要求
sbatch --gres=gpu:2 train.sh # 타입 무관 2장
sbatch --gres=gpu:a100:2 train.sh # a100 2장
sbatch --gpus=2 train.sh # 최신 문법
sbatch --gpus-per-node=2 --nodes=2 train.sh # 노드당 2장씩 총 4장
ジョブの中ではCUDA_VISIBLE_DEVICESが自動で設定されます。その値は物理デバイス番号ではなく、0から始まる論理番号です。コードに物理番号をハードコードしてはいけない理由です。
現場での姿
GPUの個数の不一致。ノードでGPU1枚がハードウェアエラーで消えたのに、設定はそのままです。slurmdがcountの不一致を報告して、ノードがDRAINになります。このアラートはむしろ良いものです。故障したGPUでジョブが動いておかしな結果が出るよりましです。
Cores=を書かずに性能が出ない場合。GPUとCPUが別々のソケットに配置されると、PCIeをまたいでデータが行き来します。マルチGPUの学習では特に目立ちます。
次のラボですること
slurm.confにGRESのタイプとノードごとのGPUを宣言し、gres.confを作成して、2つのファイルの個数の一致を検証するところまで行います。