日本語 English 中文
世界中のHPC専門最先端技術製品の販売・サポート

Singularity利用による共有ファイルシステムの負荷軽減

Singularity

はじめに

Singularity

前回、Pacific Teck のポートフォリオがどのようにお客様の課題を解決するのかについて、簡単にご紹介しました。その中でSingularityコンテナの利用が共有ファイルシステムのメタデータ負荷の軽減につながるという話をしました。今回はそれがどのように実現されるのかを説明します。また、同様にメタデータアクセスの抑制の効果が期待でき、かつ使ってみると便利なのにあまり知られていないOverlay機能をご紹介します。

Pythonのimport問題

例えばPythonのアプリケーションを実行した際、ライブラリのインポートが意外なほど多くのファイルをアクセスしていることが問題視されてきています。そこで、以下のようにしてその実態を確認してみましょう。

まずpipを用いて、ユーザーのホームディレクトリにnumpyとscipyをインストールし、それをインポートするだけの処理をstraceでログを取りながら実行します。終了後にホームディレクトリ内へのopenとstatの数を確認した結果です。

[pteck@pteck01 ~]$ pip3 install --user numpy
[pteck@pteck01 ~]$ pip3 install --user scipy
[pteck@pteck01 ~]$ strace -o strace.python.log python3
Python 3.6.8 (default, Nov 16 2020, 16:55:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> import scipy as sp
>>>
[pteck@pteck01 ~]$ grep '/home/pteck'  python.strace.log  | grep ^open | wc -l
150
[pteck@pteck01 ~]$ grep '/home/pteck'  python.strace.log  | grep ^stat | wc -l
560

まだ何の処理もしていないにもかかわらず、ホームディレクトリ以下に対するファイルオープンが150回、statは560回にも及びました。同様にPyTorch(CPUのみ対応版)を以下の通りインストールし、PyTorch Quickstartに記載されているimportをした場合について計測してみます。

[pteck@pteck01 ~]$ pip3 install --user torch==1.10.0+cpu torchvision==0.11.1+cpu torchaudio==0.10.0+cpu -f https://download.pytorch.org/whl/cpu/torch_stable.html
<<中略>>
[pteck@pteck01 ~]$ strace -o strace-raw-pytorch-2.log python3
Python 3.6.8 (default, Nov 16 2020, 16:55:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import torch
>>> from torch import nn
>>> from torch.utils.data import DataLoader
>>> from torchvision import datasets
>>> from torchvision.transforms import ToTensor, Lambda, Compose
>>> import matplotlib.pyplot as plt
>>>
[pteck@pteck01 ~]$ grep /home/pteck strace-raw-pytorch.log  |grep ^open  |wc -l
1112
[pteck@pteck01 ~]$ grep /home/pteck strace-raw-pytorch.log  |grep ^stat  |wc -l
3362

なんとこれだけで1000回以上のファイルオープンがあります。これらがクラスター上で同時実行されたならばメタデータの負荷に直結します。当然ながら一度に数百万ファイルにアクセスするようなジョブと比較すれば、効果は微々たるものになるかもしれませんが、多数のジョブが走るクラスター環境では無視できないと思います。これをSingularityを使って解消しましょう。

【解決策1】SIFイメージにライブラリ群を埋め込んでしまう

アプリケーションの実行環境を作るのに、以下のような定義ファイルを用いてSingularityのイメージ内にライブラリをインストールすると、共有ファイルシステムへのアクセスをほぼ撲滅することができます。

[pteck@pteck01 ~]$ cat pytorch.def
Bootstrap: docker
From: ubuntu:20.04
%post
    yum -y install python3-pip zlib1g-dev build-essential
    pip3 install torch==1.10.0+cpu torchvision==0.11.1+cpu torchaudio==0.10.0+cpu -f https://download.pytorch.org/whl/cpu/torch_stable.html
    yum clean all
%runscript
    python3 $*
[pteck@pteck01 ~]$ singularity build -f pytorch pytorch.def
<<中略>>
[pteck@pteck01 ~]$ ./pytorch example.py

ここで、%postでのインストールがコンテナ内のroot権限で実行され、ユーザーのホームディレクトリではなくシステム側にインストールされるというのがポイントです。これで同じimportではSIFイメージの中にだけアクセスが発生するため、共有ファイルシステムへメタデータアクセスは発生しません。

実際に2台のPC間でNFSでホームディレクトリを共有しているシステムで試してみました。無線LAN経由ということもあり、パフォーマンスはふらつきますが、何度も試せば傾向を取ることはできます。実行したのはPytorchのimportのみの処理です。処理の合間にNFSサーバー側でキャッシュをドロップしています。

[share@pteck01 ~]$ /usr/bin/time python3 torchimport.py
2.80user 0.67system 0:19.82elapsed 17%CPU (0avgtext+0avgdata 144652maxresident)k
0inputs+0outputs (0major+59318minor)pagefaults 0swaps
[share@pteck01 ~]$ /usr/bin/time python3 torchimport.py
2.78user 0.67system 0:14.29elapsed 24%CPU (0avgtext+0avgdata 144644maxresident)k
0inputs+0outputs (0major+59300minor)pagefaults 0swaps
[share@pteck01 ~]$ /usr/bin/time python3 torchimport.py
2.80user 0.62system 0:17.26elapsed 19%CPU (0avgtext+0avgdata 144648maxresident)k
0inputs+0outputs (0major+59317minor)pagefaults 0swaps
[share@pteck01 ~]$ /usr/bin/time python3 torchimport.py
2.83user 0.63system 0:18.67elapsed 18%CPU (0avgtext+0avgdata 144648maxresident)k
0inputs+0outputs (0major+59302minor)pagefaults 0swaps

なんとimportのみで最大20秒かかっています。キャッシュを残したまま繰り返し同じことをすると1.8秒程度で動くこともありますが、それでも4秒を超えることもあり、安定しません。一方でSingularityを使うとオーバーヘッドがあるため2秒を切ることはないものの、ほぼ2.4秒程度のまったく同一の時間で安定して起動してきます。Userタイムが半分で終わることにも注目してください。

[share@pteck01 ~]$ /usr/bin/time ./pyt3.sif python3 torchimport.py
1.26user 1.24system 0:02.33elapsed 107%CPU (0avgtext+0avgdata 142008maxresident)k
103264inputs+0outputs (653major+52249minor)pagefaults 0swaps
[share@pteck01 ~]$ /usr/bin/time ./pyt3.sif python3 torchimport.py
1.30user 1.25system 0:02.41elapsed 105%CPU (0avgtext+0avgdata 142008maxresident)k
103264inputs+0outputs (653major+52611minor)pagefaults 0swaps
[share@pteck01 ~]$ /usr/bin/time ./pyt3.sif python3 torchimport.py
1.24user 1.25system 0:02.36elapsed 105%CPU (0avgtext+0avgdata 142008maxresident)k
103264inputs+0outputs (653major+52433minor)pagefaults 0swaps
[share@pteck01 ~]$ /usr/bin/time ./pyt3.sif python3 torchimport.py
1.23user 1.23system 0:02.32elapsed 106%CPU (0avgtext+0avgdata 142008maxresident)k
103264inputs+0outputs (653major+52074minor)pagefaults 0swaps

【解決策2】OverlayFS を用いて高頻度のI/Oをオフロード

SIFの実体はSquashFSという圧縮ファイルシステムでリードオンリーです。そのため、ホスト側とデフォルトで共有されるホームディレクトリや/tmp等、-Bオプションでバインドするディレクトリを除き、システム側には書き込みができません。例えば特定のディレクトリをスクラッチ領域とするような使い方では工夫が必要です。SingularityはOverlayFSを用いて、書き込みできる領域をコンテナに重ね合わせて使うことができます。これにより、例えば特定部分のみが異なるイメージを別々に作ることなく、着せ替え人形のような運用が可能です。

Overlay機能には2種類あり、メインメモリを実体とするtmpfsを用いてコンテナ起動時のみ書き込み可能とする揮発的な--writable-tmpfsオプションと、外部にイメージファイルを用意して、書き込んだ内容を再利用可能とする--overlayオプションです。

tmpfsを用いる場合はsingularity exec, run, shellのオプションとして--writable-tmpfsを付けるだけです。

[pteck@pteck01 ~]$ singularity shell --writable-tmpfs centos.sif
Singularity> mkdir /scratch
Singularity> touch /scratch/hoge
Singularity> ls -al /scratch
total 0
drwxrwxr-x 2 pteck pteck 60 Dec 14 12:28 .
drwxr-xr-x 1 pteck pteck 60 Dec 14 12:28 ..
-rw-rw-r-- 1 pteck pteck  0 Dec 14 12:28 hoge

この方法はメモリを使うため、極めて高速なI/Oを実現できますが、サイズに注意する必要があります。また、揮発性なのでコンテナ終了時に内容は全て失われます。

次に、OverlayFSのイメージを作成しますが、簡単のためにSingularityCE 3.8以降をご用意ください。Overlay用のイメージにはいくつか満たすべき要件があります。以前はddコマンド等で作成した空ファイルにファイルシステムを作り、必要なディレクトリを内部に作成していましたが、SingularityCE 3.8から、Overlayイメージを自動作成する機能が追加されました。PROは2021年12月現在の最新リリースのベースが3.7なので未実装ですが、近日リリースされる予定の3.9(1月19日にリリースされました。)には搭載されています。ただしRHEL/CentOS7をお使いの場合は、そのままではこの機能が使えませんので、本記事のAppnendixを参照ください。

[pteck@pteck01 ~]$ singularity overlay create --size 1024 --create-dir /usr/share/apps overlay.img

これでOverlayFS形式になった1GBのoverlay.imgが作成できます。この書式では内部に/usr/share/appsディレクトリが作成済みとなっています。例としてここに何らかのリファレンスデータ等を展開して入れます。

[pteck@pteck01 ~]$ singularity exec --overlay overlay.img core.sif tar xzf reference-data.tar.gz -C /usr/share/apps

書き込まれたデータはoverlay.imgファイル内に展開され、何度でも再利用ができます。

[pteck@pteck01 ~]$ singularity exec --overlay overlay.img core.sif ls -al /usr/share/apps
total 20
drwxr-xr-x.   4 pteck pteck   51 Jul 19  2020 .
drwxr-xr-x. 167 pteck pteck 4096 Mar 19  2021 ..
drwxr-xr-x.   2 pteck pteck   23 Jul 19  2020 config
drwxr-xr-x.   3 pteck pteck   17 Dec 16  2020 metadata
-rw-r--r--.   1 pteck pteck 8838 Mar 23  2020 reference.xml

バリエーションを複数用意して、実行時に使うイメージを選択するという使い方もできますし、処理結果を取り出すのに使うこともできます。参照回数が多いデータは共有ファイルシステムに展開してあるものにアクセスするより、こうしてOverlayFSのイメージに保存しておくことでメタデータの負荷を上げずに済みます。なお、OverlayFSは、ディレクトリツリーを透過的に重ね合わせますが、同じものがあればOverlay側を優先するので、予めファイルやディレクトリを用意してイメージの内容を改変して使うことが可能です。ただし、以下のように既存ディレクトリやファイルを操作しようとすると、当然Permission Deniedになります。

Singularity> mkdir /opt/fuga
mkdir: cannot create directory ‘/opt/hoge’: Permission denied
Singularity> touch /etc/os-release
touch: cannot touch ‘/etc/os-release’: Permission denied

これらもイメージ内にあらかじめ用意しておけば書き込みできるようになります。また、OverlayイメージをSIFに組み込んで統合し、1ファイルにしまうことも可能です。詳しくは公式のドキュメントを参照してください。

まとめ

メタデータアクセス負荷により共有ファイルシステムのパフォーマンスが低下するというのは、世界中のスパコンで問題となっているようです。Singularityを用いてその軽減をはかれるテクニックをご紹介しました。ご活用いただいて、快適で効率的な計算環境の構築に貢献できたら幸いです。
Singularity PRO及び、Singularity Enterpriseのご用命は弊社までご連絡ください。

Appendix

OverlayFS用のイメージはext3で作られますが、singularity overlay createコマンドではe2fsprogsの最近のバージョン(-dオプションが使えるもの)が必要となるため、RHEL/CentOS7では使えないという問題があります。対処方法として、少々アクロバティックですが、CentOS8やUbuntu20.04等の最近のバージョンをベースにしたSIFイメージにSingularityをインストールしておき、そちらを使うという事ができます。

[pteck@centos7 ~]$ singularity overlay create cent7.img
FATAL:   mkfs.ext3 seems too old as it doesn’t support -d, this is required to create the overlay layout
[pteck@centos7 ~]$ cat sing.def
Bootstrap: docker
From: centos:8
%post
    yum install -y https://github.com/sylabs/singularity/releases/download/v3.9.2/singularity-ce-3.9.2-1.el8.x86_64.rpm
    yum install -y e2fsprogs
    yum clean all
[pteck@centos7 ~]$ singularity build -f sing.sif sing.def
[pteck@centos7 ~]$ ./sing.sif singularity overlay create –size 1024 centos7.img