概要
たまたまDGX H100を借りられたので、ちょっと使いやすくする為にslurmを入れてみました。
8個ではなくjob単位で1つずつGPUをつかえると良いなというモチベーションです。
また、単一ノードのため、アカウント機能などは使っておらず、最小構成くらいのノリです。
パッケージのインストール
DGXOSは、最初からリポジトリが設定されているので以下のようにそのままインストールするだけで終わります。
sudo apt-get update
sudo apt-get install -y slurm-wlm slurm-wlm-doc munge #slurm-wlm 23.11.4がインストールされる
認証を追加
v23.11からslurm単体認証が可能になったようですが、mungeの方が簡単そうなので、今回は外部認証を使います。
※keyはノード間で共通である必要があります。今回は1ノードなので何も考えなくていいです。
if [ ! -f /etc/munge/munge.key ]; then
sudo mungekey --create
fi
sudo chown munge:munge /etc/munge/munge.key
sudo chmod 400 /etc/munge/munge.key
sudo systemctl enable munge
sudo systemctl restart munge
slurmの設定を書く
sudo vim /etc/slurm/slurm.conf
# DGX H100 単一ノード構成
ClusterName=dgx
SlurmctldHost=dgxh100
SlurmUser=slurm
# 認証
AuthType=auth/munge
CryptoType=crypto/munge
# プロセス管理
ProctrackType=proctrack/cgroup
TaskPlugin=task/cgroup,task/affinity
# スケジューリング
SchedulerType=sched/backfill
SelectType=select/cons_tres
SelectTypeParameters=CR_Core_Memory
DefMemPerNode=257989
StateSaveLocation=/var/spool/slurm/ctld
SlurmdSpoolDir=/var/spool/slurm/d
# ログ
SlurmctldLogFile=/var/log/slurm/slurmctld.log
SlurmdLogFile=/var/log/slurm/slurmd.log
SlurmctldPidFile=/run/slurmctld.pid
SlurmdPidFile=/run/slurmd.pid
# GPU設定
GresTypes=gpu
# ノード定義
NodeName=dgxh100 CPUs=224 Sockets=2 CoresPerSocket=56 ThreadsPerCore=2 RealMemory=2063917 Gres=gpu:8 State=UNKNOWN
# パーティション
PartitionName=gpu Nodes=dgxh100 Default=YES MaxTime=INFINITE State=UP
# MPI設定(私の環境にはmpiが不要なのでNoneを指定)
MpiDefault=none
ノード定義にあるNodeName=dgxh100 CPUs=224 Sockets=2 CoresPerSocket=56 ThreadsPerCore=2 RealMemory=2063917 Gres=gpu:8 State=UNKNOWNは各ホストに合わせていい感じに修正する必要があります。
--memを指定してなく、かつDefMemPerNodeを設定していないと1jobに全てのメモリを与えるため、1ジョブしか実行できなくなります。RealMemory / GPU数(= 1/8)を設定することで、各ジョブがメモリの1/8だけを使用し、8ジョブの並列実行が可能になります。
リソースの隔離を行うためにcgroup.confを設定する
sudo vim /etc/slurm/cgroup.conf
CgroupPlugin=autodetect
ConstrainCores=yes
ConstrainDevices=yes
ConstrainRAMSpace=yes
ログなどに必要なディレクトリの作成
sudo mkdir -p /var/log/slurm /var/spool/slurm/ctld /var/spool/slurm/d
sudo chown -R slurm:slurm /var/log/slurm /var/spool/slurm
GPUの登録を行う
GPU_COUNT=$(nvidia-smi -L | wc -l)
{
for i in $(seq 0 $((GPU_COUNT - 1))); do
echo "Name=gpu File=/dev/nvidia$i"
done
} | sudo tee /etc/slurm/gres.conf > /dev/null
いざ実行してみる
systemctlの起動
sudo systemctl enable slurmctld slurmd
sudo systemctl restart slurmctld
sleep 2
sudo systemctl restart slurmd
sleep 2
初回起動時はノードがState=UNKNOWNのままなので、手動でidleに切り替えます。
sudo scontrol update nodename=dgxh100 state=idle
sinfoでidleになっていれば準備完了です。
$ sinfo
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
gpu* up infinite 1 idle dgxh100
sbatchの実行
$ sbatch --gpus=1 --wrap='nvidia-smi -L; echo CUDA_VISIBLE_DEVICES=$CUDA_VISIBLE_DEVICES'
Submitted batch job 7
squeueで確認すると(InvalidAccount)と表示されることがありますが、アカウンティング機能を使っていないために出る表示で、ジョブの実行には影響しません。(私の環境では、30秒程度で実際に実行されました。)
(Slurm 23.11ではAccountingStorageType=accounting_storage/noneは廃止されており、未設定=アカウンティング無効が正しい設定とのことでした。)
出力ファイルを確認します。
$ cat slurm-7.out
GPU 0: NVIDIA H100 80GB HBM3 (UUID: GPU-xxxx)
CUDA_VISIBLE_DEVICES=0
CUDA_VISIBLE_DEVICES=0 が表示されていれば、1ジョブ=1GPUの隔離が正しく動作しています。