本当は怖いHPC

HPC屋の趣味&実益ブログ

UCXを試すメモ(1)

最近、ネットワークライブラリのUCXを試しています。

GitHub - openucx/ucx: Unified Communication X (mailing list - https://elist.ornl.gov/mailman/listinfo/ucx-group):

ドキュメントを生成

まずはドキュメントをビルドするために、手元のMacにリポジトリを落としてみます。

$  brew install autoreconf automake doxygen graphviz
# これ以外にpdflatexが必要

$ git clone https://github.com/openucx/ucx.git
$ cd ucx
$ ./autogen.sh
$ ./configure --with-docs-only
$ make docs

で、いくつかLatex関係のエラーが出るが、ひとまず全て q を入力して強引に通過。 doc/doxygen-doc/ucx.pdf にドキュメントのPDFが出力されている。ここまでに既に1時間くらい使ってしまった…

UCXの全体像

UCXは、乱立していた高速インターコネクトの抽象化ライブラリを統合する目的で開始されたプロジェクトです。 ハードウェア(と、そのネイティブAPI)と、構築される特定のプログラミングモデルのライブラリの中間を埋めるライブラリです。

ハードウェアとしては、Openfabricsベース製品(Infiniband、RoCE、iWARP)、Cray GEMINI、Intel Omni-Path(旧Qlogic)などがあります。一方で、特定のプログラミングモデルを提供するライブラリとしてはMPI、OpenSHMEM、GASNETなどがあります。

UCXは、これらの中間を埋める統一ライブラリとして作られています。

ライブラリは、3つのコンポーネントからなっています。

UCS

UCSは、Service layer と呼ばれ、UCXライブラリ全般に渡って使われるユーティリティを提供します。

  • Atomic操作
  • スレッド関連
  • メモリ管理
  • データ構造

UCT

UCT は、transport layer で、通信層を抽象化するコンポーネントです。メモリ間のデータの転送が抽象化され、メモリには、アクセラレーター(GPU)のメモリも含まれます。

UCP

UCP は、上位の高レベルライブラリによって使われるであろう機能を提供するコンポーネントです。

  • 初期化
  • AMO (Atomic memory operation)
  • Tag Matching(通信のタグ付け)
  • Stream
  • Active Message(メッセージの到着と共にコールバックが起動されるようなもの)
  • Collective(集団通信)

HPC向け高速通信ネットワークのAPI/ライブラリのメモ。

メモ

(この文章では、「ライブラリ」と「フレームワーク」は特に区別していません。)

スパコンを始めとするHPC環境では、インターコネクトとしてInfinibandやOmniPath、50G/100G Ethernetなどの高速ネットワークが利用されています。多くの場合、これらの環境上ではMPIを始めとする標準ライブラリが使用されるため、その下のAPIに注意を向けることは殆どありません。しかし、以下の様な場合は低レベルAPIや薄いラッパーライブラリを直接使うことを考える必要があります。

  • MPIでは不十分だったり目的に適さない場合
  • 性能を極限まで引き出したい場合
  • あるいは単に好奇心から勉強したい場合

以下が、高速インターコネクトハードウェアと、そのネイティブAPIの一覧です。

インターコネクト メーカー ネイティブAPI
Infiniband 標準 ib verbs
RoCE 標準 verbs
iWarp 標準 verbs
Tofu Fujitsu
Omni-Path Intel PSM2
GNI Cray GNI API
IBM Torus Network IBM PAMI

さらに、MPIやOpenSHMEMなどの高レベルライブラリと、上記の低レベルAPIの間には さらにラッパーライブラリが存在します。

ライブラリの一例

  • libfabric
    • verbs API群の置き換えを狙って開発されているフレームワーク。レイヤーとしては上記のネイティブAPIに近いかも
  • GASNET
    • PGAS言語への適用を念頭に置いたライブラリ。
  • UCX
    • いろいろ乱立しているネイティブAPIを低いオーバーヘッドで共通化することを狙っているフレームワーク。Open MPI、OpenSHMEM等での採用をスタート地点として開発されているらしい。個人的にはこれが有望っぽい。

ここらへん、ドキュメントが少なくて一握りの人間にしか使えないAPIが多くて、抽象度や依存関係の間隔が非常にわかりにくいですね。

ChainerMN入門以前

この記事は,Chainer Advent Calendar 2017の13日目の記事です.

ChainerMNの入門については別途記事を書こうかと思っていますが, 今回は「入門以前」について書いてみたいと思います.誰が/何を目的としてChainerMNを導入すべきか, 導入に際して何が必要で/何に注意する必要があるか,などです.

ChainerMNとは

ChainerMNは,複数のGPU(もしくは計算機)を活用して,時間のかかる 深層学習の学習プロセスを高速化するためのChainerの追加パッケージです. 複数のGPU,複数の計算機というのは,主にネットワークで接続された 複数の計算機を指します.

なお,必ずしも1台の計算機であっても,内部で複数のプロセスを走らせることによって ChainerMNを使用することも可能です.

単に多数のGPUを同時に使うというだけなら,複数の異なるパラメーターでの 実験を同時に走らせること(パラメーターサーベイ)でも達成できます. ChainerMNは,パラメーターサーベイと何が違うのでしょうか?

パラメーターサーベイの場合,実験の結果が出るまでの時間(Time to solution)は1GPUの時と変わりません. もし,並行して試した多数のパラメーターが不要なものであったことがわかったら, 大きなGPU時間が無駄になってしまいます. また,ベイズ最適化など,実験の結果を見ながらハイパーパラメーターを徐々に最適化していく プロセスでは,パラメーターサーベイのようなやり方でGPUを多数同時に使うことは できません.

それに対し,ChainerMNでは,1つあたりの実験の時間を短くできるので, 1つ1つの実験の結果を見ながらパラメータを探索していくことができます. これにより,GPU時間をムダにすることなく多数のGPUを使って 研究開発時間を短縮できます.

注意事項

ChainerMNを使う上での注意事項は,大きくわけて2つあります.

第1点:速度を速くするには速いネットワークが必要

1つ目の重要な点は,適切なハードウェアを使うということです. 端的に言ってしまえば,ChainerMNで実験を効果的に高速化するためには 高速なネットワークを使う必要があります. 理想的には,Infinibandというスパコンで用いられるネットワークを用いることが 推奨されます.実際,Preferred Networkがブログで公開している実験では, Infiniband FDRという,1レーンあたり56Gbpsの速度を出せるネットワークを用いています.

現在のChainerMNは「データ並列・同期型」というアプローチを採用しているため, 通信が遅いと,全体の計算時間がそれに引っ張られて遅くなってしまいます. 最悪の場合,「2台のマシンで4GPUにしたのに,1台のマシンで2GPUのときより 遅くなった」ということになってしまいます.

現在一般に用いられているEthernetだと,データセンターでは10Gbps,家庭用だと 下手をすると1Gbpsのものもあります.このようなネットワークの場合, ダブルバッファリングや通信圧縮などのような技術を用いて,通信のボトルネックを 回避する工夫が必要になります.

現状 AWSのp3インスタンスでは,25Gbps Ethernetが提供されています. これであれば,10Gbps Ethernetよりは高速な通信が期待できます. しかし,ノード内ではNVLINKによるGPU間通信が提供されているため, 通常のChainerMNの使い方ではその利点を最大限に活かすことはできない可能性があります.

もし,近い将来に高速なネットワークを用いた複数台構成のクラスタの導入予定が ないのであれば,あえてChainerMNを用いずに,MultiprocessParallelUpdaterを用いるのも 1つの手です.

2点目:Large batchによる精度低下に注意する

データ同期型の並列化によって分散計算をするということは, いわゆるミニバッチサイズを大きくすることに相当します.一般的には, バッチサイズは大きすぎず小さすぎずが良いとされ,大きすぎるバッチサイズは 学習モデルの精度低下を招くとされています.

よって,自分のモデルがバッチサイズの増加に対してどのような振る舞いをするのかを 注意深く観察し,どの程度の精度低下が起こり,それがどの程度許容されるのかを 考えておく必要があります.

場合によっては,様々な論文で提供されている精度低下を防ぐテクニック()を 用いる必要があるかもしれません.

まとめ

・ChainerMNは,データ並列・同期型の並列・分散計算を提供するChainerの追加パッケージです ・ChainerMNの性能を引き出すには,GPUに加えて高速なネットワークが必要です(投資が必要です) ・場合によってはMultiprocessParallelUpdaterで十分な場合もあります ・Large Batchの罠に注意しましょう

ありがとうございました!

【広告】