TT Lab
はじめる
学ぶ 学習パス コース

HPCとSlurm

GPUを口約束で分け合うと起きること

TT Labで続きを見る

一言でいうと

バッチスケジューラーは、誰がいつ何を使うかを、人の合意ではなくポリシーで決めるシステムです。

なぜ必要なのか

GPUサーバーが1台のうちは、こうします。「今使っていますか。」「いいえ、どうぞ。」これでうまく回ります。

2台になってユーザーが5人になると、Slackに予約用のスレッドができます。3台になってユーザーが10人になると、こんなことが起きます。

これらの問題に共通するのは、リソースの割り当てが状態として管理されていないことです。スケジューラーはそれをキューとポリシーに置き換えます。

どう動くのか

Slurmの構成要素

構成要素 役割 どこで動くか
slurmctld 中央のコントローラー。キューの管理とスケジューリングの判断を行う 管理ノード1台(HA構成では2台)
slurmd 各計算ノードのエージェント。ジョブを実行する すべての計算ノード
slurmdbd アカウントと使用量のデータベース(任意) 管理ノード
munge ノード間の認証 すべてのノード

mungeはこの構成で最も頻繁に問題を起こします。クラスターのすべてのノードが同じmungeキーを持っていて、時計も合っている必要があります(既定の許容誤差は数分です)。キーが違ったり時計がずれたりするとMunge decode failedが出て、ノード同士が通信できません。

ls -l /etc/munge/munge.key      # 0400, munge:munge 여야 한다

権限が少しでも緩いと、mungedはそもそも起動しません。

スケジューリングの基本概念

バックフィル(backfill)

基本のスケジューラーは優先度の順にジョブを配置します。ところが、大きなジョブがリソースを待っている間にノードが遊んでしまうことがあります。バックフィルは、前のジョブの開始時刻を遅らせない範囲で、後ろの小さなジョブを先に埋め込みます。

バックフィルがうまく動くには、ユーザーが--timeを正直に書く必要があります。全員が最大値を書くと、スケジューラーは隙間を計算できません。そのため成熟したクラスターは、「短く書けば早く動く」というインセンティブをポリシーとして作ります。

リソース要求の意味

sbatch --nodes=1 --ntasks=1 --cpus-per-task=8 --mem=64G --gres=gpu:a100:2 --time=04:00:00 train.sh

要求していないリソースは使えません。cgroupで強制されるため、--gres=gpu:1で受け取ったのにコードから2枚使おうとすると、2枚目はそもそも見えません。

キューが進まない理由の読み方

バッチスケジューラーを入れたあとに最もよく聞くのは、「自分のジョブが動かない」という言葉です。 Slurmはその理由を状態文字列で教えてくれるので、表を知っていればたいていは自分で解決できます。

squeue -u $USER -o "%.10i %.9P %.20j %.8T %.10M %R"
scontrol show job <작업번호> | grep -E 'JobState|Reason|NodeList'
理由 意味 たいていの解決方法
Resources 要求したリソースが今は空いていません 待ちます。要求を減らすと早くなります
Priority 前に優先度の高いジョブがあります フェアシェアポリシーの問題です
QOSMaxJobsPerUserLimit そのQoSの同時実行数の上限です 配列ジョブにまとめます
AssocGrpCPUMinutesLimit アカウントの割り当て量を使い切りました 管理者に連絡します
ReqNodeNotAvail そのノードが予約中か停止中です ノードの指定を外します
PartitionTimeLimit 要求した時間がパーティションの上限より長いです --timeを短くします

要求を大きくするほど、長く待ちます。ノード4台を8時間要求すると、それだけの空き枠ができるまで待つことになります。バックフィル(backfill)スケジューラーは短くて小さなジョブを隙間に差し込むので、--timeを正直に(余裕はあっても過剰にならないように)書くと、はるかに早く始まります。上限いっぱいに書いておく習慣は、自分自身を後回しにしてしまいます。

ノードがdrainなら、理由が書かれています。

sinfo -R          # drain 사유 목록
scontrol show node <노드> | grep -E 'State|Reason'

ディスク不足、GPUエラー、ヘルスチェックの失敗がほとんどです。理由を消さずにノードだけを復帰させても、次の検査でまた外されます。

ジョブが落ちたのに理由がわからないときは、アカウンティングの記録を見ます。標準出力に何も残らずに消えてしまう場合は、sacctが終了コードとともにOUT_OF_MEMORYやTIMEOUTを教えてくれます。

sacct -j <작업번호> --format=JobID,State,ExitCode,MaxRSS,Elapsed,ReqMem

MaxRSSがReqMemに張り付いていれば、メモリが原因です。

現場での姿

ホームラボでも意味があります。GPUが2枚のサーバーでも、複数の実験を順番に回す必要があるならスケジューラーを使うほうが楽です。夜のうちにキューへ入れておけば、自動で続けて動きます。そしてその経験は、そのまま大規模なクラスターにつながります。

ノードがDRAINで外れること。ハードウェアエラーやGRESの不一致が検出されると、Slurmはそのノードを自動で外します。原因を直したあと、scontrol update NodeName=... State=RESUMEで復帰させる必要があります。自動では戻りません。これを知らないと、ノード1台が何日も遊んだままになります。

次の確認で見ること

続くクイズではまず、パーティション・バックフィル・リソース要求がそれぞれどのようなスケジューリングの判断を生むのかを確認します。その基準を通過したら、次のモジュールからslurm.confの作成、GPU GRESの定義、sbatchスクリプト、壊れた設定の診断を順に実習します。