MPI並列アプリケーション編
本ドキュメントは、リソースマネージャーをOpenPBSからSlurmへ移行する際のリファレンスです。
特に、GPUクラスターで多用される nccl-tests を例に、ベアメタル実行、Enroot/Pyxis、Singularity、および mpirun を用いた実行方法について説明します。
1. 基本コマンド・ディレクティブの対応表
OpenPBSのジョブスクリプト(#PBS)をSlurm(#SBATCH)に変換するための基本ルールです。
機能 | OpenPBS (#PBS) | Slurm (#SBATCH) | 備考 |
ジョブ投入 | qsub script.sh | sbatch script.sh | |
ジョブ確認 | qstat | squeue | |
ジョブキャンセル | qdel | scancel | |
ノード数 | -l nodes=2 | --nodes=2 | |
ノードあたりタスク数 | ppn=8 | --ntasks-per-node=8 | MPIランク数に相当 |
GPU数 | -l ngpus=8 | --gres=gpu:8 | ノードあたりのGPU数 |
キュー/パーティション | -q workq | --partition=workq | |
1タスクあたりCPUコア数 | ompthreads=4 | --cpus-per-task=4 | |
最大実行時間 | -l walltime=01:00:00 | --time=01:00:00 | |
標準出力パス | -o /path/to/out | --output=/path/to/out | %jはジョブIDに置換 |
ジョブ名 | -N name | --job-name=name |
2. 実行例
2-1. nccl-tests のバイナリ実行 (srun を使用)
Slurm環境で最も推奨される「Slurmネイティブ」な実行方法です。srun が各ノードのリソースとMPIプロセスの起動を管理します。
#!/bin/bash
#SBATCH --job-name=nccl_srun
#SBATCH --nodes=2
#SBATCH --ntasks-per-node=8
#SBATCH --gres=gpu:8
#SBATCH --partition=workq
#SBATCH --cpus-per-task=10
#SBATCH --output=%j.out
# モジュールのロード(環境に合わせて変更)
module load cuda/13.2.0 hpcx-mt/v2.25.1-gcc-cuda13
# srunを使うと、Slurmが確保した全ノードに対して自動的にプロセスを配布します。
# hostfileの指定や -np の計算は不要です。
srun /path/to/nccl-tests/build/all_reduce_perf -b 8 -e 128M -f 2 -g 1script.sh
2-2:Enroot / Pyxis によるコンテナ実行
Pyxisプラグインが導入されている場合、srun のオプションだけでコンテナ実行が可能です。Dockerイメージをそのまま利用できるため、現在のディープラーニング環境では主流の実行方法です。
#!/bin/bash
#SBATCH --job-name=nccl_pyxis
#SBATCH --nodes=2
#SBATCH --ntasks-per-node=8
#SBATCH --gres=gpu:8
#SBATCH --partition=workq
# NGCなどのDockerイメージを直接指定
IMAGE="nvcr.io/nvidia/pytorch:24.01-py3"
# --container-image: 使用するイメージを指定
# --container-mounts: ホストのディレクトリをマウント (source:dest)
srun --container-image="${IMAGE}" \
--container-mounts=/home/user/data:/data \
/workspace/nccl-tests/build/all_reduce_perf -b 8 -e 256M -f 2 -g 1script.sh
2-3:Singularity (Apptainer) による実行
HPC環境で標準的なSingularity (Apptainer) を使用する場合です。srun の後にコンテナ起動コマンドを記述します。
#!/bin/bash
#SBATCH --job-name=nccl_singularity
#SBATCH --nodes=2
#SBATCH --ntasks-per-node=8
#SBATCH --gres=gpu:8
#SBATCH --partition=workq
# SIFイメージのパス
CONTAINER="/path/to/images/nccl-tests.sif"
# srun を通じて全ノードで singularity を起動
# --nv オプションでホストのGPUドライバを利用
srun singularity exec --nv "${CONTAINER}" \
/usr/local/bin/all_reduce_perf -b 8 -e 128M -f 2 -g 1script.sh
2-4:mpirun / mpiexec を使用する方法 (srunを使わない)
OpenPBSの記述に近い方法で実行したい場合や、MPI固有のチューニングオプション(OpenMPIのMCAパラメータなど)を細かく制御したい場合に適しています。
参考:
NVIDIA HPC SDK Release Notes — HPC SDK Release Notes 25.1 documentation
Welcome to version 25.1 of the NVIDIA HPC SDK, a comprehensive suite of compilers and libraries enabling developers to program the entire HPC platform, from the GPU foundation to the CPU and out through the interconnect. The 25.1 release of the HPC SDK includes component updates as well as important functionality and performance improvements.
https://docs.nvidia.com/hpc-sdk/archive/25.1/hpc-sdk-release-notes/index.html#release-component-versions
#!/bin/bash
#SBATCH --nodes=2
#SBATCH --ntasks-per-node=8
#SBATCH --gres=gpu:8
#SBATCH --partition=workq
module load hpcx-mt/v2.25.1-gcc-cuda
# Slurm環境下でビルドされたOpenMPIであれば、
# mpirunは自動的にSlurmのリソースを検知します。
mpirun /path/to/nccl-tests/build/all_reduce_perf -b 8 -e 128M -g 1script.sh
3. まとめ:移行時のヒント
- srun vs mpirun:
- srun: Slurmと深く統合されており、プロセスの配置やCPUのアフィニティ管理が強力です。
- mpirun: OpenPBS時代のスクリプトを流用しやすく、MPI層での制御に慣れている場合に適しています。
- ホストファイルの不要化:
Slurm環境では、srunもmpirun(対応版)も、Slurmが設定した環境変数($SLURM_JOB_NODELISTなど)から自動的にノードを認識するため、手動でホストリストを作成する必要はありません。
- 環境変数の継承:
Slurmはデフォルトでジョブ投入時の環境変数を引き継ぎます。意図しない挙動を防ぐには #SBATCH --export=NONE を指定し、スクリプト内で必要な module load を行うのが安全です。