ナード戦隊データマン

機械学習, 自然言語処理, データサイエンスについてのブログ

slurmでZero Bytes were transmitted or receivedが出たときに行った対処

slurmはジョブを複数の計算ノードに分散実行するために使えるミドルウェアですが、Zero Bytes were transmitted or receivedというエラーが頻発したため、行った対処方法をメモします。

TL;DR

$HOME内の読み書きの頻度を減らし、巨大なファイルはs3へアップロードしてバケットをマウントして読み込もう。

slurmの仕様の一つ

slurmのQ&Aを見てみると、以下のように書かれている部分があります:

The srun command normally terminates when the standard output and error I/O from the spawned tasks end. https://slurm.schedmd.com/faq.html#force

つまり、タスクから標準出力や標準エラーが受け取れなくなった場合は終了します。これが、おそらくZero Bytes were transmitted or receivedというメッセージに関係していると考えました。

対処方法1: タスク実行中は常に標準出力を生成する

タスクを実行している間は常に標準出力を生成するようにするために、以下の単純なフィルタープログラムを作成します:

[timer_out.py]

import sys
import time
from multiprocessing import Process


def print_symbol(symbol=".", sleep=0.4):
    while True:
        print(symbol, end='', flush=True)
        time.sleep(sleep)


if __name__ == "__main__":
    p = Process(target=print_symbol, args=(".", ))
    p.start()
    for line in sys.stdin:
        print("\n" + line, flush=True)
    p.terminate()
    while p.is_alive():
        pass
    p.close()

これを以下のように目的のプログラムと連携することで、実行中はドットを出力します:

$ ./target_program | python3 timer_out.py

対処方法2: NFS内での読み書きを減らす

実際のところ、対処方法1を実行しても同じエラーが出てしまいました。そこで、aws parallelclusterでslurmを使う場合、以下のようにすることでNFS($HOME)への読み書きを減らします:

  1. 読み込んで使うだけのあらゆるファイルは、s3上にアップロードし、それをgoofysでマウントして使う。
  2. 一時的に生成されるファイルは計算インスタンス内で生成する。(そのためにボリュームサイズを増やす必要あり)
  3. 最終出力として残ったファイルだけ、$HOMEへ移動する。あるいは、移動専用のs3ストレージを使う。
  4. HOMEで共有するのは、軽量な設定ファイルやvirtualenvで生成したvenvディレクトリなど、読み書きの頻度の少ないものに限定する。

なぜこのエラーが発生したか

一応、上記の2つの設定によってエラーを回避することができましたが、以下の原因によってエラーが発生したと考えています。

  • slurmのログは$HOME内にあり、計算インスタンスから受け取った標準出力とエラー出力を書き込んでいる。
  • s3上に置く前は$HOME内に巨大なファイルをおいて共有して使っていたが、これらのファイルの読み込みが通信の過負荷を生んだ。
  • NFSへの通信の過負荷により、標準出力やその他のメッセージを受信できなくなった。
  • 受信できない時間が一定時間経過し、slurmが当該エラーを吐いた。
  • slurmが当該エラーを吐くノードの状態を変更し、DOWNになった。

要するに、通信の過負荷によってメッセージ受信ができない、というような問題である可能性が高いと考えました。実際、s3をマウントするよう変更したところ、slurmログは正常に出力されるようになり、プログラムの実行時間は数倍高速化されました。

ちなみに、一般的には、このエラーが発生する状況は読み書きの問題だけではありません。一般的にはクロックの同期の問題に起因することが多いようです。

参考

  1. Slurm Workload Manager - Frequently Asked Questions
  2. https://forums.aws.amazon.com/thread.jspa?threadID=235976
  3. 2002 – error: slurm_receive_msg: Zero Bytes were transmitted or received

余談

インフラ知識が乏しいため、この種の問題が発生することはかなり勉強になっている気がする。論理的なことだけを考えてプログラムを書くと物理的制約を無視しがちになってしまうが、「NFSへの読み書きの頻度」といったネットワークやIOの帯域の問題を考慮しなければならないケースもあるよな、と。