Skip to content

東北大学 MASAMUNE-II の概要と基本操作

MASAMUNE-弐は、計算・解析・学習を大規模に実行するための共有型HPC環境である。資源配分はジョブ投入(PBS)で行い、ログインノードは作業入口、計算は計算ノードで進める運用である。

alt text

参考ドキュメント

1. 位置づけと全体像

1.1 システムの考え方

HPCの利用は、端末からリレーサーバ経由でログインし、フロントエンドで準備(ソース取得、ビルド、入力生成、短い前処理)を行い、計算ノードへジョブとして処理を渡して実行する流れである。結果はストレージへ出力し、必要に応じて可視化や統計処理を行う。

1.2 計算資源の区分

MASAMUNE-弐は、用途により大きく次の系統に分かれる。

  • スケールアウト(CPU計算ノード群)
    • 多数ノードへ並列に広げて回す計算(MPI、メッシュ計算、DFTの並列化、パラメータスイープなど)に向く。
  • スケールアップ(GPU計算ノード群)
    • GPUを用いる深層学習、GPU対応分子動力学、GPUソルバ、あるいは単一ノード内で強力に回す計算に向く。

キュー(待ち行列)は、ノード専有のもの、共有のもの、デバッグや対話用途に近いものがあり、資源上限や優先度が異なる。

2. ログインと接続

2.1 SSHの基本

外部から直接ログインノードへ入るのではなく、SSHリレーサーバを経由してフロントエンドへ接続する構成である。公開鍵認証を前提にする。

代表的な接続形(概念)は次である。

  1. ローカル端末 → SSHリレーサーバ(例:jsshr01)
  2. SSHリレーサーバ → フロントエンド(例:super1 / gpu1 など)

接続先ホスト名や方式は、必ず公式の「接続先ホスト名一覧」に従うこと。

2.2 .ssh/config の例(ProxyJump)

手元端末で二段ログインを簡素化するには、ProxyJump を用いる。

sshconfig
Host masamune-relay
  HostName jsshr01.example
  User your_user
  IdentityFile ~/.ssh/id_ed25519

Host masamune-super
  HostName super1.example
  User your_user
  IdentityFile ~/.ssh/id_ed25519
  ProxyJump masamune-relay

HostName は実際の一覧に従って置き換えること。

2.3 ログインノードと計算ノードの役割分担

ログイン直後に入るフロントエンド(super系、gpu系)は、編集・ビルド・軽い確認を想定した場である。計算負荷の高い処理(学習、巨大な解析、長時間の前処理)は計算ノードへ投げるのが基本である。

3. ストレージ構成とデータ配置

3.1 主要領域の使い分け

ストレージは役割によって分けて使う。

代表パス役割向くデータ注意
/home個人環境・設定・小さめのコードdotfiles, 環境設定, 小容量の成果物容量制限がある。バックアップ対象外の扱いが明記されているため重要データは別途保全を考える。
/work大きめの計算データ置き場入出力ファイル、学習データ、計算ログ共有領域であるため整理と容量配慮が必要である。
/work/scratch 等一時領域(高速・短期)中間ファイル、展開物、途中生成物一定期間アクセスが無いと自動削除される設定がある。

設計上は、再生成できる中間物は scratch、成果物や再利用データは /work、個人環境は /home に置く分離が安全である。

3.2 使用量の確認

領域の使用量はコマンドで確認できる。Lustre系では lfs quota などでクォータ確認が可能な場合がある。公式の確認方法に従うこと。

4. ジョブ投入(PBS)の考え方

4.1 なぜジョブ投入が必要か

共有資源を公平に使うため、計算資源(CPU/GPU/メモリ/実行時間)は申告し、スケジューラが並べ替えて割り当てる。対話実行であっても、qsub -I で計算ノードを確保してから行う設計である。

4.2 ジョブの基本構造

PBSでは、次の2通りがある。

  • バッチジョブ:スクリプトを qsub で投げ、完了まで自動実行する。
  • 対話ジョブ:qsub -I で計算ノードへ入り、その場でコマンドを実行する。

どちらも「キューを選ぶ」「資源を指定する」が中心である。

5. キューの選び方

キュー名・上限は変更される可能性があるため、最新の公式「キュー一覧」を参照すること。ここでは選び方の考え方をまとめる。

5.1 対話用途

対話的に計算ノードを確保して作業する用途である。GPUの情報が必要な場合は GPU側の対話キューを用いる指針が示されている。

例:対話でCPU 2コア、メモリ8GBを確保する。

bash
qsub -I -q IP_001 -l select=1:ncpus=2:mem=8gb

5.2 共有キュー

共有キューは、小規模に回す用途である。GPUが必要なら GPU共有キューを用いる指針が示されている。

共有キューでの書式:

GPU共有
qsub -q キュー名 [ -I ] [ -l select=1[:ncpus=...][:ngpus=...][:mem=...] ] スクリプト
CPU共有
qsub -q キュー名 [ -I ] [ -l select=1[:ncpus=...][:mem=...] ] スクリプト

5.3 デバッグ用途

短時間で成否を確認する用途である。GPUが必要なら GPU側のデバッグキューを用いる指針が示されている。

5.4 ノード専有

ノード専有は大規模に回す用途である。CPU計算ノード群を束ねて使う想定である。

6. ジョブスクリプトの基本形

6.1 構成

#!/bin/sh
#PBS -q CP_001
#PBS -l select=1:ncpus=28:mem=112gb
#PBS -N sample_job

cd "$PBS_O_WORKDIR"
./a.out > stdout.txt 2> stderr.txt

6.2 重要な環境変数

PBSでは、ジョブ実行時に便利な変数が与えられる。

変数意味
PBS_O_WORKDIRqsub を実行したディレクトリ
PBS_NODEFILE割り当てノード一覧が書かれたファイル

加えて、実装上よく参照されるものとして、次がある。

変数意味
PBS_JOBIDジョブID(ログファイル名や出力ディレクトリ名に使うことが多い)
PBS_QUEUE投入キュー名
PBS_NCPUS割当CPU総数(環境によっては提供されない場合もある)
TMPDIRノードローカル一時領域(設定される場合がある)

環境変数の有無は環境に依存するため、ジョブ内で env | sort の出力を一度保存しておくと確認が容易である。

7. MPIジョブ(多ノード並列)の実行

7.1 PBSで確保されたノードとMPIの接続

MPIは、ジョブで確保されたノード上で実行する。PBSでは割当ノード一覧が $PBS_NODEFILE として渡されるため、これを hostfile として mpirun に渡して起動する形が基本である。

bash
#!/bin/sh
#PBS -q CP_001
#PBS -l select=2:ncpus=28:mem=112gb
#PBS -N mpi_2node

cd "$PBS_O_WORKDIR"

# ノード一覧の確認
uniq -c "$PBS_NODEFILE" > nodes.summary.txt

# 例:2ノード×28コア=56プロセス
mpirun -np 56 -ppn 28 -hostfile "$PBS_NODEFILE" ./a.out > result.out 2> result.err

ここで select=2 は2ノード確保の意味であり、-np の総プロセス数と -ppn のノード当たりプロセス数が整合している必要がある。

7.2 CPUバインドと性能の考え方

MPI並列は、プロセス配置とメモリアクセス(NUMA)に強く依存する。アプリによっては、CPUバインド(コア固定)が有効になる場合がある。具体的な指定方法はMPI実装やシステム設定に依存するため、公式マニュアルとサンプルに従うのが安全である。

7.3 I/Oが支配的になる場合

多ノードで並列化しても速くならない場合、I/O(大量の小ファイル出力、頻繁なログ)や同期が支配している可能性がある。出力頻度の調整、集約出力、scratchの利用などで改善することがある。

8. GPU計算と深層学習

8.1 GPU資源指定(ngpus)

GPUを使う場合は、GPUを許すキューを選び、ngpus を指定する。共有GPUキューではデフォルト割当がある場合もあるが、学習ではCPU側前処理やメモリが支配することも多く、ncpus と mem を明示した方が意図通りになりやすい。

例:GPU 1枚、CPU 8コア、メモリ32GB

qsub -q CA_001 -l select=1:ncpus=8:ngpus=1:mem=32gb -l walltime=04:00:00 run_train.pbs

8.2 GPUが見えているかの確認(ジョブ内)

GPUジョブ内では、まずGPUが割り当てられていることを確認するのが確実である。

#!/bin/sh
#PBS -q CA_001
#PBS -l select=1:ncpus=4:ngpus=1:mem=16gb
#PBS -l walltime=00:30:00
#PBS -N gpu_check

cd "$PBS_O_WORKDIR"

nvidia-smi
python -c "import torch; print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'no gpu')"

PyTorchが無い環境なら import で落ちるため、その場合は環境ロード(conda等)後に実行する。

8.3 学習ジョブの例(PyTorch想定)

#!/bin/sh
#PBS -q CA_001
#PBS -l select=1:ncpus=8:ngpus=1:mem=32gb
#PBS -l walltime=04:00:00
#PBS -N torch_train

cd "$PBS_O_WORKDIR"

# conda例(環境名は自分のものに合わせる)
# source ~/miniforge3/etc/profile.d/conda.sh
# conda activate torch

export OMP_NUM_THREADS=8

python train.py --config config.yaml

学習がDataLoaderで詰まる場合、CPUコア数、ワーカ数、ストレージ位置(/workかscratchか)で体感が大きく変わることがある。

8.4 複数GPU・分散学習

複数GPUを使う場合、単一ノード内(ngpus>1)と複数ノード(select>1)の2形態がある。起動は torchrun がよく用いられるが、NCCLのネットワーク設定、ノード間通信、キューの上限に依存するため、まずは単一ノード複数GPUで成立させてから拡張する考え方が安定する。

9. Python環境(pyenv)と実行位置

9.1 pyenv の導入

ユーザー領域へ pyenv を導入する方法として、所定スクリプトが案内されている。

bash /work/app/pyenv/pyenv-setup.bash

ログイン時に環境が有効化されるよう、bash設定へ追記する形が示されている。

echo "source /work/app/pyenv/bash_env" >> ~/.bash_profile

有効化後は、pyenv versions や python --version で確認する。

9.2 Pythonは計算ノードで実行する理由

Pythonは前処理・特徴量生成・学習でCPU/メモリ/I/Oを使い切りやすい。フロントエンドでの重い実行は避け、対話ジョブまたはバッチジョブで計算ノードへ流す方針である。

対話で計算ノードを確保する例:

qsub -I -q IP_001 -l select=1:ncpus=4:mem=16gb

10. CCMS JupyterLab

10.1 JupyterLabの考え方

JupyterLabはローカルPCのブラウザで使い、計算環境側では計算ノード上にJupyterサーバを立ち上げる形になる。外部から直接ポートへ入れないため、SSHトンネルでローカルへ転送する。

10.2 SSHトンネル

bash
# ssh -L 8888:localhost:8888 your_user@super1.example

この上で、計算環境側で jupyter lab --no-browser --port 8888 のように起動し、ローカルの localhost へ接続する流れになる。正確な手順は公式のJupyterLab手順に従うこと。

11. ジョブの状態確認と操作

11.1 状態確認(qstat)

ジョブ管理は qstat を中心に行う。PBSではジョブが「投入 → 待機 → 実行 → 終了」という状態遷移を持ち、状態確認は原因切り分けの起点になる。

操作代表コマンド得られる情報
自分のジョブ一覧qstatJOBID、キュー、状態、実行ノードの概要
ユーザー指定qstat -u useruser のジョブ一覧(混雑状況の把握にも使える)
詳細表示qstat -f JOBID資源割当、実行ホスト、開始時刻、出力先などの詳細

状態(State)は環境や表示形式によるが、概念として次を押さえると読みやすい。

状態の概念意味
待機スケジューラが資源を割り当てる順番待ちである
実行計算ノード上で実行中である
終了正常終了または異常終了で終了した状態である
保留何らかの理由で投入はされているが進行が止められている

詳細表示では、要求した select/ncpus/ngpus/mem/walltime と実際の割当が整合しているかを確認できる。

11.2 削除(qdel)と保留(qhold / qrls)

ジョブの停止・制御系コマンドは次である。

操作代表コマンド意味
削除qdel JOBIDジョブを終了させる(実行中なら強制停止になる)
保留qhold JOBIDジョブを保留状態にする(スケジューラ処理を止める)
保留解除qrls JOBID保留を解除して通常状態へ戻す

削除は計算途中のファイルが不完全な形で残ることがある。長時間の計算や学習では、途中保存(チェックポイント)を一定間隔で出す設計にしておくと回復が容易である。

11.3 標準出力と標準エラーの扱い

PBSのジョブは通常、標準出力(stdout)と標準エラー(stderr)がファイルへ保存される。ジョブスクリプト内で > out.txt 2> err.txt と明示しておくと、追跡が簡潔になる。

例:

bash
./a.out > stdout.txt 2> stderr.txt

学習や解析では、stderrにライブラリ依存エラー、CUDA周りの失敗、メモリ不足などが出ることが多い。

12. ノード時間消費(配分・消費の概念)

12.1 定義

ノード時間消費は、実行時間と使用ノード数に基づいて計上され、計算ノード種別により係数が異なる。一般形は次である。

Tnode=Texec×Nnode×α
  • Texec:実行時間(時間)
  • Nnode:使用ノード数
  • α:係数(ノード種別・キュー種別で定義)

ここで α は同一壁時計でも「資源種別によって重み付けが異なる」ことを表す。GPUノードが高い係数を持つ設計は、限られた高価な資源を公平に配分するための考え方に対応する。

12.2 解釈

同じ壁時計時間でもノード数を増やすと消費は増える。したがって、並列化して壁時計が短くなっても、短縮が十分でなければ総消費は増える。

例として、係数が同じ(α一定)として比較する。

  • 1ノードで10時間:Tnode=10×1×α=10α
  • 2ノードで6時間:Tnode=6×2×α=12α

壁時計は10→6時間に短くなったが、消費は10α→12αへ増える。並列化にはこのようなトレードオフがある。

12.3 最低限押さえるべき2つの観点

ノード時間の扱いは、次の2観点で整理すると混乱しにくい。

観点目的見る量
壁時計時間人間の待ち時間を短くするTexec
消費効率限られた割当を長く使うTnode

研究開発では「壁時計を短くして反復回数を増やす」ことが価値になる場面が多い一方、割当が厳しい場合は「消費効率を上げて試行回数を確保する」方が価値になる場面もある。目的関数が異なるため、同じ最適化にはならない。

12.4 消費を抑えやすい設計の方向

消費そのものを抑えるには、次の方向が効くことが多い。

  • 過剰な資源申告を避け、必要量に合わせる(ncpus, mem, ngpus)
  • 強い並列化よりも、単ノードで高効率(プロセス数、OpenMP、GPU利用率)
  • I/O律速や同期待ちを減らす(小ファイル乱発の抑制、集約出力)
  • 試行段階に応じてキューを使い分ける(短時間検算→本番)

ここで重要なのは、消費の式が「時間×ノード数×係数」である以上、時間短縮が成立しない並列化は消費面では悪化しやすい、という構造である。

13. 解析・学習の進め方(構成例)

13.1 計算から解析への接続

計算ログやバイナリ出力を、そのまま解析へ流すとI/Oに支配されやすい。次のように段階を分けると扱いやすい。

  1. 計算:計算ノードで生成(/work や scratch)
  2. 集約:必要な量だけを抽出し、軽量フォーマットへ変換(CSV/Parquet/HDF5等)
  3. 統計:分布、相関、外れ値の把握
  4. 学習:訓練・評価・推論
  5. 可視化:図表の出力と記録

この分離は「同じ処理を再実行しやすくする」効果も持つ。再現性の観点では、集約データと学習条件(乱数種、ハイパーパラメータ、コードのコミット)を一緒に保存する設計が望ましい。

13.2 ストレージとI/Oの考え方

並列ファイルシステムは大容量・高スループット向きである一方、小ファイルを大量に作ったり、極端に高頻度で書いたりすると性能が出にくいことがある。そこで、次の方向が有効になりやすい。

  • 計算中に生成する中間物は scratch へ置く
  • 出力ファイル数を減らす(ステップごとではなく間引く、まとめて書く)
  • 学習ログは「必要な情報だけ」を保存し、頻度を抑える
  • 終了後に成果物だけ /work へ移す

13.3 解析系ジョブの例(概念)

計算結果の集約や特徴量生成も、計算ノードでバッチジョブとして回す方が安定する。

bash
#!/bin/sh
#PBS -q CP_001
#PBS -l select=1:ncpus=8:mem=64gb
#PBS -l walltime=02:00:00
#PBS -N postprocess

cd "$PBS_O_WORKDIR"

# conda例
# source ~/miniforge3/etc/profile.d/conda.sh
# conda activate analysis

python aggregate_results.py --input /work/your_project/raw --output /work/your_project/agg/results.parquet

解析がメモリに乗らない場合は、分割集約(チャンク処理)に変えると成立しやすい。

13.4 小さな検算

本番サイズの前に、短い壁時計時間・小さなデータで成否を確認してから拡張する。具体例として次がある。

  • 10分以内で終わる壁時計指定にして、スクリプトと環境が成立するかを見
  • 入力データの1%だけを使って、前処理から学習までが一連で回るかを見る
  • 1ノードのみでスケールの傾向を掴んでから多ノードへ拡張する

14. よく遭遇する状況と対処の考え方

14.1 状況を分類する

同じ「遅い」「落ちる」でも原因は大きく異なる。最初に次の分類を置くと整理がしやすい。

分類症状の例見るべき手掛かり
スケジューラ要因待機時間が長い、すぐ開始されないqstat の状態、要求資源の大きさ、walltime
資源不足途中で停止、プロセスが落ちるstderr、ログ末尾、メモリ不足の痕跡
I/O律速CPU/GPUが遊ぶ、進捗が断続的出力頻度、ファイル数、入出力の場所
環境不整合import失敗、MPIやCUDA関連エラーstderr、ライブラリのバージョン、起動方法

分類は「原因を決めつける」ためではなく、「見る順序を固定する」ために行う。現象の収束が早くなる。

14.2 状況別の方向性

次の表は、遭遇しやすい状況と、考えるべき主因の候補、対処の方向を対応づけたものである。

状況主因の候補対処の方向
ジョブが開始されないキュー混雑、要求資源過大、walltime長すぎまず小さく成立させる(短いwalltime、少ない資源)→成立後に拡張する
開始するがすぐ落ちる実行ファイルの参照ミス、入力ファイル不足、環境変数不足$PBS_O_WORKDIR を基点にパスを揃える、必要ファイルの存在確認、stderrを見る
途中で落ちる(数分〜数時間後)メモリ不足、I/O過多、数値的不安定mem指定を増やす、出力頻度を下げる、ログに異常値が出ていないか確認する
速度が出ない並列効率低下、I/O律速、GPU未使用並列度を下げて比較、I/O削減、GPU利用状況の確認
ノード数を増やしても速くならない通信・同期支配、I/O支配、負荷不均等多ノード化の前に単ノード効率を上げる、出力の集約、プロセス配置の見直し
/home が埋まる中間物やログが蓄積/workやscratchに移し、成果物だけ残す設計に寄せる
scratch からデータが消えた維持期間超過、ポリシーに基づく削除再生成できないデータは /work へ退避する設計にする

この表の「対処の方向」は、最初にやるべき一手を固定するためのものである。個別ケースの最適解は計算内容により変化する。

14.3 PBS資源指定の整合を確認する観点

ジョブが不安定な場合、資源指定(select/ncpus/mem/ngpus/walltime)が計算の実態とズレていることが多い。次の観点で整合を見る。

  • CPU計算:ncpusとプロセス/スレッド数(MPIの -np、OpenMPの OMP_NUM_THREADS)が一致しているか
  • GPU計算:ngpusと、アプリが要求するGPU枚数が一致しているか
  • メモリ:memが明らかに小さくないか(解析や学習は特に大きい)
  • walltime:短すぎて途中で打ち切られていないか

OpenMP併用の概念例:

bash
export OMP_NUM_THREADS=8
mpirun -np 4 -ppn 4 -hostfile "$PBS_NODEFILE" ./a.out

この例では、MPI 4プロセス×OpenMP 8スレッドで総スレッドは32相当になりうる。ncpusとの整合が崩れていると、速度低下や不安定さの要因になりうる。

14.4 標準出力・標準エラーの設計

異常終了の情報はstderrに残ることが多い。stdoutとstderrを分けると読みやすい。

例:

./a.out > stdout.txt 2> stderr.txt

学習系では、stderrにCUDAがらみの失敗(デバイス未認識、メモリ不足、ドライバ整合不良、ライブラリ不足)が出ることが多い。

14.5 GPU学習で起きやすい現象の整理

GPUを確保しても学習が遅い場合、GPUではなく入力供給(CPU側)やI/Oが支配していることがある。

  • データ読み込みが遅い:ストレージI/Oが律速になり、GPUが待つ
  • 前処理が重い:CPUコア不足でDataLoaderが追いつかない
  • ログ出力が多い:ステップごとに大量出力すると学習が止まる
  • バッチが小さい:GPUが十分に埋まらず使用率が上がらない

この場合、CPUコア数、DataLoaderワーカ数、データ配置(/workかscratchか)、ログ頻度で改善することがある。GPUの使用状況は nvidia-smi で確認する。

14.6 学習ジョブの再現性の確保(最低限)

同じ結果を再現できるようにするには、次を一緒に残すのが合理的である。

  • 実行したコード(コミットID、またはアーカイブ)
  • 使った環境(conda環境名、pip freeze等の依存)
  • 入力データの版(生成元と変換条件)
  • 乱数種(seed)
  • 学習条件(ハイパーパラメータ、エポック、バッチ)

これらは「後から原因を追える」状態を作るための最低限の情報である。

まとめ

MASAMUNE-II(MASAMUNE-弐)は、CPU占有・CPU共用・スケールアップ・GPU占有・GPU共用という複数の資源形態と、並列ファイルシステムを組み合わせて、データ解析と機械学習を大規模に進められる基盤である。キュー定義と消費時間の考え方、ストレージ領域の性格、PBS系ジョブ操作(qsub/qstat)を基礎として身につけると、処理の性質に合わせた資源選択ができ、解析の再現性も保ちやすくなる。

参考資料