はじめに
松尾研LLM開発コンペ2025では、H100 GPU × 24基という大規模GPU環境を使う機会がありました。
普段ローカルPCやGoogle Colabで動かすのとは全く違うため、環境構築にはかなり苦労しました。
本記事では、私が環境構築の中で実際に行った手順やハマりどころを 「再現性重視の実務メモ」 として整理します。
「Slurmって何?」「conda環境の切り替えで失敗する…」という方の参考になれば幸いです。
1. 環境構築の全体像
環境構築は以下のステップで進めました。
Step1. ログインノードにアクセス
Step2. リポジトリを取得(GitHub)
Step3. 計算ノードに移行しリソース確保(Slurm)
Step4. conda環境を有効化(+必要なモジュールをロード)
Step5. Slurm経由でジョブ実行
2. 実際の手順
Step1. ログインノードにアクセス
クラスタ環境では、まずログインノードに入ってから計算ノードを確保します。
ssh username@cluster.example.com
Step2. Githubリポジトリの取得
今回はGitHubで公開されているSakana AIのRLTをベースに開発するので、ログインノード上の作業ディレクトリにリポジトリをクローンします。
git clone https://github.com/SakanaAI/RLT.git /workspace/llm_project/sakanaai/RLT
cd /workspace/llm_project/sakanaai/RLT
注意点
- Username for 'https://github.com' と表示されたらトークンを入力。
普段はUIからDLすることが多かったので、LinuxコマンドでSSH認証→クローンの流れは新鮮でした。特にSSH鍵の設定で苦労しました。
Step3. 計算ノードに移行(リソース確保)
ログインノードで学習ジョブを実行するとリソース不足になるため、Slurmで計算ノードを確保します。
salloc -p P07 -N2 --nodelist=osk-gpu[70-71] \
--ntasks-per-node=1 --gpus-per-node=2 \
--cpus-per-task=12 --mem=64G --time=03:00:00
主なオプション
- -p P07 : パーティション指定
- -N2 : ノード数(例:2台)
- --nodelist=osk-gpu[70-71] : 使用するノードを指定
- --gpus-per-node=2 : 各ノードで使用するGPU数
- --cpus-per-task=12 : 1タスクに割り当てるCPUコア数
- --mem=64G : メモリ割り当て
- --time=03:00:00 : 実行時間の上限
Step4. conda環境の有効化(+必要なモジュールをロード)
計算ノードに移行後は チーム共通のconda環境 を有効化します。
クラスタ環境では、まず必要なモジュールをロードしてからcondaを使えるようにする必要があります。
今回のコンペはチーム開発なので、チーム共通のconda環境があれば、それを使うのが再現性と効率性の面でベストです。
module reset
module load miniconda/24.7.1-py311
source /opt/conda/etc/profile.d/conda.sh
conda activate /workspace/llm_project/envs/multi_sft_and_vllm
注意点
- module reset で一度クリーンな状態にする
- module load で必要なモジュールを読み込む(クラスタによって内容は異なるので module avail で確認)
- source .../conda.sh をしないと conda activate が使えない
- source activate ではなく conda activate を使う
Step5. Slurmでジョブ実行
実行環境が構築できたら、Slurmを使ってジョブを投入します。
ここでは例として「学習ジョブをまとめたシェルスクリプト」を実行しています。
srun -p P07 -N2 --nodelist=osk-gpu[70-71] \
--ntasks-per-node=1 --gpus-per-node=2 \
--cpus-per-task=12 --mem=64G \
--time=03:00:00 \
bash train_job.sh
train_job.sh は、環境変数の設定や python train.py の実行コマンドをまとめた
ジョブ実行用スクリプト を想定しています。
3. ハマりどころと解決策
① Github SSH認証エラー
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.
原因: SSH鍵がGitHubに登録されていない、または権限が不足している。
解決:
- ローカルで ssh-keygen を実行し、公開鍵をGitHubに登録する。
- ssh -T git@github.com で疎通確認。
② ログインノードでジョブを実行してしまう
python train.py
ログインノードで直接実行すると、GPUが割り当てられずエラーや強制終了につながります。
原因: 計算ノードに移行していない。
解決: salloc や srun を使い、必ず計算ノード上で実行する。
確認方法:
nvidia-smi
③ conda環境が切り替わらない
ModuleNotFoundError: No module named 'transformers'
原因: conda環境が正しく有効化されていない。
解決: which pythonで正しいパスを確認する。
which python
# => /workspace/llm_project/envs/multi_sft_and_vllm/bin/python
まとめ
正直、最初は「自分にできるのか…?」という不安が大きく、実際にエラーとの闘いの連続でした。
ただ、一つひとつのエラーを切り分け、調べ、解決していく中で、Slurmの仕組みやconda環境の正しい扱い方 を自然と身につけることができました。
そして、計算ノード上でGPUを使ったジョブが動き出した瞬間は、これまでの苦労が報われるような大きな達成感がありました。
ローカルやColabとはまったく違うスケール感の中で、「自分の手で大規模環境を動かせた」という実感 は、技術的な学び以上に大きな財産です。
今回の経験を通じて「エラーとの格闘も含めて開発の醍醐味」だと気づけたことが、一番の収穫だったように思います。
次回は 「Hydra設定編」 として、実験でよく使うパラメータをどのように整備し、実際に学習を回したのか をご紹介します。
おまけ:基本確認コマンド集
大規模環境では「エラーが出てから直す」よりも、「まず確認する」習慣が重要だと痛感しました。
以下は今回エラー対応時に使用した確認コマンドです。
システム環境の確認
「どのノードで実行しているか」「GPUが見えているか」を切り分けるときに使用します。
hostname # どのノードにいるか
pwd # 現在の作業ディレクトリ
nvidia-smi # GPU状態の確認
nvcc --version # CUDAのバージョン確認
conda環境の確認
Pythonがどの環境を参照しているかを確かめ、依存関係エラーを切り分けるときに使用します。
conda env list # 環境一覧
which python # 実際に使われているPythonパス
python - <<'PY'
import torch, transformers
print("torch:", torch.__version__, "cuda?", torch.cuda.is_available())
print("transformers:", transformers.__version__)
PY
Slurmジョブの確認
ジョブがキューに入っているか、終了しているかを把握します。
squeue -u $USER # 自分のジョブのキュー状況
sacct -u $USER --format=JobID,State,ExitCode,Elapsed,NodeList -X --starttime $(date -d '1 day ago' +%F)
ファイル/設定の確認
ジョブ実行スクリプトや設定ファイルの存在を確認します。
ls -l run_step3.sh
ls conf/*.yaml
環境変数の確認
学習に必要なトークンや通信設定が正しく渡っているかをチェックします。
echo $HF_TOKEN
echo $WANDB_MODE
echo $MASTER_ADDR
echo $MASTER_PORT