Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
Python 分散処理再入門
DB Analytics showcase Sapport 2017
(株)HPCソリューションズ 飯坂剛一
今日の話題
• Data処理について
• Python での分散処理
– threading / multiprocessing
– joblib
– dask/distributed
– mpi4py
今日の話題にしないこと
• Python の文法とか
• モジュールやフレームワークの詳細
なんとなく判ったつもりでOK
About me
• 飯坂 剛一 (いいさか ごういち)
– (株) HPCソリューションズ
– go.iisaka@hpc-sol.co.jp / iisaka51@gmail.com
– 普段は...役務やコンサルタントをしています。
• ...
Data処理
たとえばDeepLearningでのデータ処理
• 画像の数が少なければ良い結果が得られない
– 多数のデータを収集
• 画像のクラス分類が重要
– 対応する画像だけに分類/変換/加工
MNIST データ・セット
• 国立標準技術研究所の
混合データ セット
• 合計70,000 枚の画像
– 学習用60,000 枚
– 判別用10,000 枚
• 28x28ピクセル
CIFAR-10 データ・セット
• 10カテゴリのデータ・セット
• 合計60,00枚のカラー画像
– 学習用50000枚
• 各クラス5,000枚
– 判別用10000枚
• 各クラス1,000枚
• 32x32ピクセル
• Pythonの...
Google Cat
• コンピュータが「猫」がどういうもの
かを教示されることなく、
自力で「猫」を認識できた
– 強く反応するニューロンが生まれた
• YouTube にある動画から
200x200ピクセルの画像を
1000万枚取得
• 1...
為替取引: AlpacaAlgo
為替取引でのデータ
• 通貨ペアごとのデータを保持
– USDJPY, EURUSD, EURJPY, GBPUSD, GBPJPY...
• 各時間単位での売値(Bit), 買値(Ask)の時系列データ
– 1M, 1D, 4H, 1H, 3...
Python
• 低い学習コストと高い可読性
• 豊富なライブラリやフレームワーク、アプリケーション
– SciPy, NumPy, Pandas, DASK, Matplotlib, Seaborn, Bokeh
– Chainer, Ten...
どのPythonがいいの?
• Anaconda Python をお勧めします
– https://www.continuum.io/downloads
Orange3: ワークフローツール
Python / Jupyter notebook のカバー領域
探索と分析
プロジェクトでnotebookのようなアプリや
Pythonを活用する
コラボレーションと公開
共有ノートブックやプロジェクトの集中管理、
エンタープライズ認証による...
Conda
• Python 3.6 が使える (Python 2.x, Python 3.x)
• x86_64, PowerPC, ARMv7 サポート
– Raspbery Pi2 でも動作する
Anaconda と Miniconda
• Miniconda は Anaconda のサブセット
• 後からパッケージは追加できるので Miniconda でOK
– 異なるバージョンの Python も追加できる
• 2つのバージョン
–...
Python での分散処理
SMP と Cluster
• SMP (Symmetric Multiprocessing)
– メモリ共有型並列コンピューティング
– 現在はほぼすべてのサーバ、PC、スマートフォンがSMP
– 処理はひとつのノード内だけで実行される
• ...
スケールアップとスケールアウト
https://www.idcf.jp/words/scaleup.html
スケールアップとスケールアウト
• スケールアップ
– 実行させるH/Wを更新することになる
– 単一ノード内での並列処理
– スレッド
• スケールアウト
– H/Wは追加するだけでよい
– プログラムをマルチノード対応化が必要
– ネットワ...
プロセスとスレッド
• 各プロセスのメモリは独立
• スレッドはプロセスのメモリを共有
https://web.kudpc.kyoto-u.ac.jp/manual/en/parallel
Pythonとスレッド
PythonでのスレッドとGIL
http://www.tivix.com/blog/lets-go-python/
GIL問題の回避方法:その1
• コードを非同期処理で書いてみる (もし可能なら)
• 主なモジュール
– gevent
– tornado
– asyncio
非同期処理が向く問題
gevent の例: イベントループ
tornado の例: コールバック
gevent と tornado の比較
• グリーンスレッド
– スレッドはハードウェアではなくアプリケーションレベルで制御される
– スレッドのようにみえるが、CPUのコンテキストスイッチは起きない
– 通常のスレッドプログラミングの問題点...
asyncio の例: (Python 3.5以降のasync/await)
asyncio async/await
• CPUコンテキストのスイッチングは起きない
– イベントループを使用しアプリケーションレベルでコルーチンを切り替える
• 競合が発生しない
– asyncio は1度に1つのコルーチンだけを実行する
...
コンテキストスイッチの発生する状況
http://ossforum.jp/node/752
GIL問題の回避方法:その2
• マルチプロセスで並列処理をすればよい
– ロックを使ってしまうと状況はかわらないことに注意
• 主なモジュール
– multiprocessing
– joblib
– DASK/distributed
– m...
マルチプロセスでの注意点
• プロセスごとに別々のメモリ領域で動作しているということ
– 変数へのアクセスには注意が必要
– データ/オブジェクトのやり取りにコツがいる
• プロセス生成とデータ/オブジェクトのコピーのオーバーヘッドがある
– ...
multiprocessing モジュール
• スレッドの替りにプロセスを生成してGILを回避
– ローカル(SMP)とリモート(Cluster)の両方で並列処理ができる
• threading モジュールと同様のAPI(よく似ている)
– s...
joblib モジュール
• タスク出力のディスクキャッシュを再遅延評価
• 簡単でシンプルな並列化処理
• 実行処理のトラッキングとロギング
• 効率的な配列バッファ処理のため大きなnumpy配列が高速
• zlibでデータ圧縮してのオブジェ...
他にもいろいろな方法がある
• Python + Spark
• Python + Hadoop
• Python + RabbitMQ
• Python + Elasticsearch
jupyter notebook の方がわかりやすいので...
DASK dashboard
DASK
• コレクション、グラフ、スケジューラで構成
• スケールアップとスケールアウト
• Out-of-Core 処理
コレクション
• Array - NumPy の array と同じインタフェース
• DataFrame - Pandas の DataFrame と同じインタフェース
• Bag - Python オブジェクトを格納
• Delayed -...
Array
import numpy as np
f = h5py.File('myfile.hdf5')
x = np.array(f['/small-data'])
x - x.mean(axis=1)
import dask.array ...
DataFrame
import pandas as pd
dd.read_csv('2015-*-*.csv')
df.groupby(df.user_id).value.mean()
import dask.dataframe as dd
...
グラフ
スケジューリング
• SMPとクラスタの両方をサポート
– 単一ノードでのスケールアップ
– クラスタでのスケールアウト
クラスタの作成
• 準備: 各ノードで distibuted のインストール
$ conda create -y -n demo
$ source activate demo
(demo) $ conda install bokeh
(demo...
スケジューラの起動
(demo) $ dask-schudler
dask-scheduler
distributed.scheduler - INFO - -------------------------------------------...
ワーカーの起動
• スケジューラの"ホスト:ポート"を引数として与える
(demo) $ dask-worker 159.203.166.31:8786 --memory-limit=auto
distributed.nanny - INFO ...
クラスタの作成 (共有ファイルシステムを使う場合)
• スケジューラの起動
• ワーカーの起動
$ dask-scheduler --scheduler-file /path/to/scheduler.json
$ dask-worker --...
クラスタの作成 (Python API)
• プログラムの中からスケジューラを起動
from distributed import Scheduler
from tornado.ioloop import IOLoop
from threadi...
クラスタの作成 (Python API)
• プログラムの中からワーカーを起動
from distributed import Worker
from tornado.ioloop import IOLoop
from threading im...
タスクの実行
• スケジューラの"ホスト:ポート"を与える
from dask.distributed import Client
client = Client('159.203.166.31:8786')
data = [client.su...
Ansible で実行環境を構築すると楽
• プレイブックで簡単にスケールアウト
jupyter notebook の方がわかりやすいので...
Blaze
• 異なるストレージシステムを抽象化してくれる
– http://blaze.pydata.org/en/latest
odo
• 簡単にデータ変換してくれる
– http://odo.pydata.org/en/latest/
MPI(Message Passing Interface)
• 並列処理をするための標準化された規格
MPI
• MPI_ではじまる関数や定数
• MPI_Init() と MPI_Finalize() に囲む
– この中でMPI関数を呼び出させる
• MPIプログラムで生成される各プロセスはランクという値が設定される
MPI: Hello World in C
mpi4py: Hello World in Python
#!/usr/bin/env python
from mpi4py import MPI
import sys
size = MPI.COMM_WORLD.Get_size()  # ...
Hello World 実行方法
$ mpicc -o helloworld.exe helloworld.c
$ mpiexec -n 4 helloworld.exe
プロセス数の指定
$ mpiexec -n 4 python hello...
conda を使うときは...
• システム側の python と混乱しやすい
• module コマンドで環境をロードするようにするとよい
– http://modules.sourceforge.net/
– 例: module load ...
mpi4py: HelloWorld - broadcast
mpi4py: HelloWorld - P2P (Send/Recv)
mpi4py: 集計 - P2P (Send/Recv)
Send/Recvの動作イメージ
https://www.nesi.org.nz/sites/default/files/mpi-in-python.pdf
mpi4py: 集計 - reduce
mpi4py: reduce の動作イメージ
https://www.nesi.org.nz/sites/default/files/mpi-in-python.pdf
画像処理: ノイズ除去シリアル版
import numpy as np
from skimage import data, img_as_float
from skimage.filter import denoise_bilateral
im...
画像処理: ノイズ除去シリアル版 (続き)
def loop(imgFiles):
for f in imgFiles:
img = img_as_float(data.load(os.path.join(noisyDir,f)))
start...
画像処理: ノイズ除去MPI版
画像処理: ノイズ除去MPI版 (続き)
def loop(imgFiles,rank):
for f in imgFiles:
img = img_as_float(data.load(os.path.join(noisyDir,f)))
s...
画像処理: ノイズ除去MPI版 (続き)
jupyter notebook の方がわかりやすいので...
GPGPU
GPGPUで使われるコンポーネント
• NVIDIA CUDA
– CuPY (Chainer)
– PyCUDA
– pygpu
• cuDNN - DeepLearning ライブラリ
• NCCL - マルチGPUを効率的に処理させる
•...
CUDA-aware MPI
• 対応するオープンソースのMPI実装
– MVAPICH2 1.8以降
– OpenMPI 1.7以降
通常のMPIでのデータ送受信
• ホスト上のメモリへのポインタのみがMPIに渡される。
• cudaMemcpyを使用してGPUバッファをホストメモリ経由で
ステージングする必要がある。
//MPI rank 0
cudaMemcpy(s_bu...
CuDA-aware MPIでのデータ送受信
• CuDA-aware MPIでは cudaMemcpy() が不要。
//MPI rank 0
MPI_Send(s_buf_d,size,MPI_CHAR,1,100,MPI_COMM_WOR...
性能比較
https://devblogs.nvidia.com/parallelforall/benchmarking-cuda-aware-mpi/
UVA(Unified Virtual Addressing)
• GPUとホストのメモリを単一仮想アドレス空間に統合
GPUDirect RDMA
• GPUのメモリ上のデータをホストのメモリを介さずにNICに直接送信
GPUDirect P2P
• 同じノード内の2つのGPUのメモリ間でバッファを直接コピーする
通常のMPIでのデータの流れ
GPUメモリ GPUメモリ
Host Buffer Host Buffer
• 2つのGPUのメモリ間に複数のバッファがあり、それぞれコピーする
通常のMPIでのデータの流れ
• それぞれのバッファでのコピーだけ時間がかかる
CUDA-aware MPI / GPUDirect P2P
GPUメモリ GPUメモリ
Host Buffer Host Buffer
• 同じシステム内の2つのGPUのメモリ間では直接コピーする
CUDA-aware MPI / GPUDirect RDMA
GPUメモリ GPUメモリ
Host Buffer Host Buffer
• 他ノードのGPUのメモリ間ではホストのメモリを経由せずにコピー
CUDA-aware MPIでのデータの流れ
• バッファへのメモリ転送が不要なので処理速度が向上する
おまけ
HPCソリューションズ HPCS-DLD
HPCS-DLD
• Anaconda Python をベースにDeepLearningの
フレームワークやライブラリ、ミドルウェアをパッケージングした
ソフトウェアディストリビューション
• それぞれのオープンソース・ライセンスに準じて無償で...
参考資料
• Anaconda Python
– https://www.continuum.io/
• NumPy
– http://www.numpy.org/
• SciPy
– https://www.scipy.org/
• Blaz...
参考資料
• Calculations with arrays bigger than your memory (Dask arrays)
– http://earthpy.org/dask.html
• mpi4py-examplpes
– ...
[db analytics showcase Sapporo 2017] A15: Pythonでの分散処理再入門 by 株式会社HPCソリューションズ 飯坂剛一
Prochain SlideShare
Chargement dans…5
×

[db analytics showcase Sapporo 2017] A15: Pythonでの分散処理再入門 by 株式会社HPCソリューションズ 飯坂剛一

1 804 vues

Publié le

Pythonは科学、数学、工学、データ分析、ディープラーニング、金融分野など多方面でよく使われる言語です。このセッションでは、Pythonでのデータ処理を高速化するための分散処理について説明してゆきます。

Publié dans : Technologie
  • Soyez le premier à commenter

[db analytics showcase Sapporo 2017] A15: Pythonでの分散処理再入門 by 株式会社HPCソリューションズ 飯坂剛一

  1. 1. Python 分散処理再入門 DB Analytics showcase Sapport 2017 (株)HPCソリューションズ 飯坂剛一
  2. 2. 今日の話題 • Data処理について • Python での分散処理 – threading / multiprocessing – joblib – dask/distributed – mpi4py
  3. 3. 今日の話題にしないこと • Python の文法とか • モジュールやフレームワークの詳細 なんとなく判ったつもりでOK
  4. 4. About me • 飯坂 剛一 (いいさか ごういち) – (株) HPCソリューションズ – go.iisaka@hpc-sol.co.jp / iisaka51@gmail.com – 普段は...役務やコンサルタントをしています。 • クラスタシステムの導入や構築 • Deep Learning プラットフォームの導入や構築 • Open Source の導入と活用方法のコンサルティング – 好きな言語: Python
  5. 5. Data処理
  6. 6. たとえばDeepLearningでのデータ処理 • 画像の数が少なければ良い結果が得られない – 多数のデータを収集 • 画像のクラス分類が重要 – 対応する画像だけに分類/変換/加工
  7. 7. MNIST データ・セット • 国立標準技術研究所の 混合データ セット • 合計70,000 枚の画像 – 学習用60,000 枚 – 判別用10,000 枚 • 28x28ピクセル
  8. 8. CIFAR-10 データ・セット • 10カテゴリのデータ・セット • 合計60,00枚のカラー画像 – 学習用50000枚 • 各クラス5,000枚 – 判別用10000枚 • 各クラス1,000枚 • 32x32ピクセル • PythonのcPickle形式
  9. 9. Google Cat • コンピュータが「猫」がどういうもの かを教示されることなく、 自力で「猫」を認識できた – 強く反応するニューロンが生まれた • YouTube にある動画から 200x200ピクセルの画像を 1000万枚取得 • 1000ノードで3日かけて学習 https://googleblog.blogspot.jp/2012/06/using-large-scale-brain-simulations-for.html
  10. 10. 為替取引: AlpacaAlgo
  11. 11. 為替取引でのデータ • 通貨ペアごとのデータを保持 – USDJPY, EURUSD, EURJPY, GBPUSD, GBPJPY... • 各時間単位での売値(Bit), 買値(Ask)の時系列データ – 1M, 1D, 4H, 1H, 30M, 15M, 5M, 1M, Tick • 各時間単位での売買ボリュームの時系列データ
  12. 12. Python • 低い学習コストと高い可読性 • 豊富なライブラリやフレームワーク、アプリケーション – SciPy, NumPy, Pandas, DASK, Matplotlib, Seaborn, Bokeh – Chainer, Tensorflow, Caffe, Orange3 • データ処理やDeepLearningで楽ができる
  13. 13. どのPythonがいいの? • Anaconda Python をお勧めします – https://www.continuum.io/downloads
  14. 14. Orange3: ワークフローツール
  15. 15. Python / Jupyter notebook のカバー領域 探索と分析 プロジェクトでnotebookのようなアプリや Pythonを活用する コラボレーションと公開 共有ノートブックやプロジェクトの集中管理、 エンタープライズ認証による安全な管理 ディプロイと運用 並列フレームワークとリソース管理の統合 アナリスト データサイエンティスト 開発者 データエンジニア DevOps https://www.continuum.io/anaconda-enterprise-notebooks
  16. 16. Conda • Python 3.6 が使える (Python 2.x, Python 3.x) • x86_64, PowerPC, ARMv7 サポート – Raspbery Pi2 でも動作する
  17. 17. Anaconda と Miniconda • Miniconda は Anaconda のサブセット • 後からパッケージは追加できるので Miniconda でOK – 異なるバージョンの Python も追加できる • 2つのバージョン – Anaconda2 / Miniconda2 - Python 2.7 – Anaconda3 / Miniconda3 - Python 3.6 • Python 2.7 は 2020/01/01 でサポート終了 – https://www.python.org/dev/peps/pep-0373/
  18. 18. Python での分散処理
  19. 19. SMP と Cluster • SMP (Symmetric Multiprocessing) – メモリ共有型並列コンピューティング – 現在はほぼすべてのサーバ、PC、スマートフォンがSMP – 処理はひとつのノード内だけで実行される • Cluster – 複数のコンピュータをネットワークで結合した並列コンピューティング – 冗長化クラスタ(HAクラスタ)と区別するために BeoWulf型クラスタやHPCクラスタと呼ばれることもある – 処理は複数のノードで実行される
  20. 20. スケールアップとスケールアウト https://www.idcf.jp/words/scaleup.html
  21. 21. スケールアップとスケールアウト • スケールアップ – 実行させるH/Wを更新することになる – 単一ノード内での並列処理 – スレッド • スケールアウト – H/Wは追加するだけでよい – プログラムをマルチノード対応化が必要 – ネットワーク性能も重要になる – マルチプロセス
  22. 22. プロセスとスレッド • 各プロセスのメモリは独立 • スレッドはプロセスのメモリを共有 https://web.kudpc.kyoto-u.ac.jp/manual/en/parallel
  23. 23. Pythonとスレッド
  24. 24. PythonでのスレッドとGIL http://www.tivix.com/blog/lets-go-python/
  25. 25. GIL問題の回避方法:その1 • コードを非同期処理で書いてみる (もし可能なら) • 主なモジュール – gevent – tornado – asyncio
  26. 26. 非同期処理が向く問題
  27. 27. gevent の例: イベントループ
  28. 28. tornado の例: コールバック
  29. 29. gevent と tornado の比較 • グリーンスレッド – スレッドはハードウェアではなくアプリケーションレベルで制御される – スレッドのようにみえるが、CPUのコンテキストスイッチは起きない – 通常のスレッドプログラミングの問題点はのこる • コールバック – スレッドプログラミングとは同じようには書けない – スレッド/コルーチンはプラグラマには隠蔽される – 例外は飲み込まれて伝わってこない – コールバックの結果を集められない
  30. 30. asyncio の例: (Python 3.5以降のasync/await)
  31. 31. asyncio async/await • CPUコンテキストのスイッチングは起きない – イベントループを使用しアプリケーションレベルでコルーチンを切り替える • 競合が発生しない – asyncio は1度に1つのコルーチンだけを実行する • デッドロックにならない – 競合が発生しないのでロックを使用する必要がなく安心 • リソースが欠乏することがない – コルーチンはスレッドで実行されるので余分なソケットやメモリが不要
  32. 32. コンテキストスイッチの発生する状況 http://ossforum.jp/node/752
  33. 33. GIL問題の回避方法:その2 • マルチプロセスで並列処理をすればよい – ロックを使ってしまうと状況はかわらないことに注意 • 主なモジュール – multiprocessing – joblib – DASK/distributed – mpi4py
  34. 34. マルチプロセスでの注意点 • プロセスごとに別々のメモリ領域で動作しているということ – 変数へのアクセスには注意が必要 – データ/オブジェクトのやり取りにコツがいる • プロセス生成とデータ/オブジェクトのコピーのオーバーヘッドがある – やみくもに並列化をせずに、もっとも効果のある部分を並列化 – 20/80セオリー:全体の20%の処理が、80%の時間を消費している • 物理コア数以上のプロセスで実行すると速度向上は期待できない – 並列度が外部に依存していることに注意する
  35. 35. multiprocessing モジュール • スレッドの替りにプロセスを生成してGILを回避 – ローカル(SMP)とリモート(Cluster)の両方で並列処理ができる • threading モジュールと同様のAPI(よく似ている) – start(), run(), join()...
  36. 36. joblib モジュール • タスク出力のディスクキャッシュを再遅延評価 • 簡単でシンプルな並列化処理 • 実行処理のトラッキングとロギング • 効率的な配列バッファ処理のため大きなnumpy配列が高速 • zlibでデータ圧縮してのオブジェクトをpickle/非pickle化 – オブジェクト階層をバイトストリームへの変換と復元
  37. 37. 他にもいろいろな方法がある • Python + Spark • Python + Hadoop • Python + RabbitMQ • Python + Elasticsearch
  38. 38. jupyter notebook の方がわかりやすいので...
  39. 39. DASK dashboard
  40. 40. DASK • コレクション、グラフ、スケジューラで構成 • スケールアップとスケールアウト • Out-of-Core 処理
  41. 41. コレクション • Array - NumPy の array と同じインタフェース • DataFrame - Pandas の DataFrame と同じインタフェース • Bag - Python オブジェクトを格納 • Delayed - 遅延評価
  42. 42. Array import numpy as np f = h5py.File('myfile.hdf5') x = np.array(f['/small-data']) x - x.mean(axis=1) import dask.array as da f = h5py.File('myfile.hdf5') x = da.from_array(f['/big-data'], chunks=(1000, 1000)) x - x.mean(axis=1).compute() • NumPyと同じように使える
  43. 43. DataFrame import pandas as pd dd.read_csv('2015-*-*.csv') df.groupby(df.user_id).value.mean() import dask.dataframe as dd df = dd.read_csv('2015-*-*.csv') df.groupby(df.user_id).value.mean().compute() • Pandas と同じように使える
  44. 44. グラフ
  45. 45. スケジューリング • SMPとクラスタの両方をサポート – 単一ノードでのスケールアップ – クラスタでのスケールアウト
  46. 46. クラスタの作成 • 準備: 各ノードで distibuted のインストール $ conda create -y -n demo $ source activate demo (demo) $ conda install bokeh (demo) $ conda install distributed
  47. 47. スケジューラの起動 (demo) $ dask-schudler dask-scheduler distributed.scheduler - INFO - ----------------------------------------------- distributed.scheduler - INFO - Scheduler at: 159.203.166.31:8786 distributed.scheduler - INFO - http at: 159.203.166.31:9786 distributed.scheduler - INFO - bokeh at: 159.203.166.31:8788 distributed.bokeh.application - INFO - Web UI: http://159.203.166.31:8787/status/ distributed.scheduler - INFO - ----------------------------------------------- distributed.scheduler - INFO - Receive client connection: 20d2354a-dd86-11e6-9fe3- a634b264672b
  48. 48. ワーカーの起動 • スケジューラの"ホスト:ポート"を引数として与える (demo) $ dask-worker 159.203.166.31:8786 --memory-limit=auto distributed.nanny - INFO - Start Nanny at: 138.197.11.22:36452 distributed.worker - INFO - Start worker at: 138.197.11.22:39702 distributed.worker - INFO - nanny at: 138.197.11.22:36452 distributed.worker - INFO - http at: 138.197.11.22:34241 distributed.worker - INFO - bokeh at: 138.197.11.22:8789 distributed.worker - INFO - Waiting to connect to: 159.203.166.31:8786 distributed.worker - INFO - ------------------------------------------------- distributed.worker - INFO - Threads: 2 distributed.worker - INFO - Memory: 2.49 GB distributed.worker - INFO - Local Directory: /tmp/nanny-xk59hltv distributed.worker - INFO - -------------------------------------------------
  49. 49. クラスタの作成 (共有ファイルシステムを使う場合) • スケジューラの起動 • ワーカーの起動 $ dask-scheduler --scheduler-file /path/to/scheduler.json $ dask-worker --scheduler-file /path/to/scheduler.json
  50. 50. クラスタの作成 (Python API) • プログラムの中からスケジューラを起動 from distributed import Scheduler from tornado.ioloop import IOLoop from threading import Thread loop = IOLoop.current() t = Thread(target=loop.start, daemon=True) t.start() s = Scheduler(loop=loop) s.start('tcp://:8786')
  51. 51. クラスタの作成 (Python API) • プログラムの中からワーカーを起動 from distributed import Worker from tornado.ioloop import IOLoop from threading import Thread loop = IOLoop.current() t = Thread(target=loop.start, daemon=True) t.start() w = Worker('tcp://159.203.166.31:8786', loop=loop) w.start()
  52. 52. タスクの実行 • スケジューラの"ホスト:ポート"を与える from dask.distributed import Client client = Client('159.203.166.31:8786') data = [client.submit(load, fn) for fn in filenames] processed = [client.submit(process, d, resources={'GPU': 1}) for d in data] final = client.submit(aggregate, processed, resources={'MEMORY': 70e9})
  53. 53. Ansible で実行環境を構築すると楽 • プレイブックで簡単にスケールアウト
  54. 54. jupyter notebook の方がわかりやすいので...
  55. 55. Blaze • 異なるストレージシステムを抽象化してくれる – http://blaze.pydata.org/en/latest
  56. 56. odo • 簡単にデータ変換してくれる – http://odo.pydata.org/en/latest/
  57. 57. MPI(Message Passing Interface) • 並列処理をするための標準化された規格
  58. 58. MPI • MPI_ではじまる関数や定数 • MPI_Init() と MPI_Finalize() に囲む – この中でMPI関数を呼び出させる • MPIプログラムで生成される各プロセスはランクという値が設定される
  59. 59. MPI: Hello World in C
  60. 60. mpi4py: Hello World in Python #!/usr/bin/env python from mpi4py import MPI import sys size = MPI.COMM_WORLD.Get_size()  # SPMD環境の規模を取得 rank = MPI.COMM_WORLD.Get_rank() # このプロセスのランク(番号) name = MPI.Get_processor_name() # このプロセスのプロセス名 sys.stdout.write( "Hello, World! I am process %d of %d on %s.n" % (rank, size, name))
  61. 61. Hello World 実行方法 $ mpicc -o helloworld.exe helloworld.c $ mpiexec -n 4 helloworld.exe プロセス数の指定 $ mpiexec -n 4 python helloworld.py
  62. 62. conda を使うときは... • システム側の python と混乱しやすい • module コマンドで環境をロードするようにするとよい – http://modules.sourceforge.net/ – 例: module load conda • conda 環境を作っていればアクティベートを忘れやすい – 例: source activate demo
  63. 63. mpi4py: HelloWorld - broadcast
  64. 64. mpi4py: HelloWorld - P2P (Send/Recv)
  65. 65. mpi4py: 集計 - P2P (Send/Recv)
  66. 66. Send/Recvの動作イメージ https://www.nesi.org.nz/sites/default/files/mpi-in-python.pdf
  67. 67. mpi4py: 集計 - reduce
  68. 68. mpi4py: reduce の動作イメージ https://www.nesi.org.nz/sites/default/files/mpi-in-python.pdf
  69. 69. 画像処理: ノイズ除去シリアル版 import numpy as np from skimage import data, img_as_float from skimage.filter import denoise_bilateral import skimage.io import os.path import time curPath = os.path.abspath(os.path.curdir) noisyDir = os.path.join(curPath,'noisy') denoisedDir = os.path.join(curPath,'denoised')
  70. 70. 画像処理: ノイズ除去シリアル版 (続き) def loop(imgFiles): for f in imgFiles: img = img_as_float(data.load(os.path.join(noisyDir,f))) startTime = time.time() img = denoise_bilateral(img, sigma_range=0.1, sigma_spatial=3), skimage.io.imsave(os.path.join(denoisedDir,f), img) print("Took %f seconds for %s" %(time.time() - startTime, f)) def serial(): total_start_time = time.time() imgFiles = ["%.4d.jpg"%x for x in range(1,101)] loop(imgFiles) print("Total time %f seconds" %(time.time() - total_start_time)) if __name__=='__main__': serial()
  71. 71. 画像処理: ノイズ除去MPI版
  72. 72. 画像処理: ノイズ除去MPI版 (続き) def loop(imgFiles,rank): for f in imgFiles: img = img_as_float(data.load(os.path.join(noisyDir,f))) startTime = time.time() img = denoise_bilateral(img, sigma_range=0.1, sigma_spatial=3), skimage.io.imsave(os.path.join(denoisedDir,f), img) print ("Process %d: Took %f seconds for %s" % ( rank, time.time() - startTime, f))
  73. 73. 画像処理: ノイズ除去MPI版 (続き)
  74. 74. jupyter notebook の方がわかりやすいので...
  75. 75. GPGPU
  76. 76. GPGPUで使われるコンポーネント • NVIDIA CUDA – CuPY (Chainer) – PyCUDA – pygpu • cuDNN - DeepLearning ライブラリ • NCCL - マルチGPUを効率的に処理させる • CUDA-aware MPI
  77. 77. CUDA-aware MPI • 対応するオープンソースのMPI実装 – MVAPICH2 1.8以降 – OpenMPI 1.7以降
  78. 78. 通常のMPIでのデータ送受信 • ホスト上のメモリへのポインタのみがMPIに渡される。 • cudaMemcpyを使用してGPUバッファをホストメモリ経由で ステージングする必要がある。 //MPI rank 0 cudaMemcpy(s_buf_h,s_buf_d,size,cudaMemcpyDeviceToHost); MPI_Send(s_buf_h,size,MPI_CHAR,1,100,MPI_COMM_WORLD); //MPI rank 1 MPI_Recv(r_buf_h,size,MPI_CHAR,0,100,MPI_COMM_WORLD, &status); cudaMemcpy(r_buf_d,r_buf_h,size,cudaMemcpyHostToDevice);
  79. 79. CuDA-aware MPIでのデータ送受信 • CuDA-aware MPIでは cudaMemcpy() が不要。 //MPI rank 0 MPI_Send(s_buf_d,size,MPI_CHAR,1,100,MPI_COMM_WORLD); //MPI rank n-1 MPI_Recv(r_buf_d,size,MPI_CHAR,0,100,MPI_COMM_WORLD, &status);
  80. 80. 性能比較 https://devblogs.nvidia.com/parallelforall/benchmarking-cuda-aware-mpi/
  81. 81. UVA(Unified Virtual Addressing) • GPUとホストのメモリを単一仮想アドレス空間に統合
  82. 82. GPUDirect RDMA • GPUのメモリ上のデータをホストのメモリを介さずにNICに直接送信
  83. 83. GPUDirect P2P • 同じノード内の2つのGPUのメモリ間でバッファを直接コピーする
  84. 84. 通常のMPIでのデータの流れ GPUメモリ GPUメモリ Host Buffer Host Buffer • 2つのGPUのメモリ間に複数のバッファがあり、それぞれコピーする
  85. 85. 通常のMPIでのデータの流れ • それぞれのバッファでのコピーだけ時間がかかる
  86. 86. CUDA-aware MPI / GPUDirect P2P GPUメモリ GPUメモリ Host Buffer Host Buffer • 同じシステム内の2つのGPUのメモリ間では直接コピーする
  87. 87. CUDA-aware MPI / GPUDirect RDMA GPUメモリ GPUメモリ Host Buffer Host Buffer • 他ノードのGPUのメモリ間ではホストのメモリを経由せずにコピー
  88. 88. CUDA-aware MPIでのデータの流れ • バッファへのメモリ転送が不要なので処理速度が向上する
  89. 89. おまけ
  90. 90. HPCソリューションズ HPCS-DLD
  91. 91. HPCS-DLD • Anaconda Python をベースにDeepLearningの フレームワークやライブラリ、ミドルウェアをパッケージングした ソフトウェアディストリビューション • それぞれのオープンソース・ライセンスに準じて無償で 使用することができます。 – http://www.hpc-sol.co.jp/dld/ • サブスクリプション契約をするとアップディトレポジトリへのアクセスと アップディトリクエストが可能になります。
  92. 92. 参考資料 • Anaconda Python – https://www.continuum.io/ • NumPy – http://www.numpy.org/ • SciPy – https://www.scipy.org/ • Blaze – http://blaze.pydata.org/ • Statsmodules – http://www.statsmodels.org/stable/index.html • Pandas – http://pandas.pydata.org/ • Blaze – http://blaze.pydata.org/ • HDF5 – https://support.hdfgroup.org/HDF5/ • matplotlib – https://matplotlib.org/ • seaborn – https://seaborn.pydata.org/ • Jupyter – http://jupyter.org/ • Orange – https://orange.biolab.si/ • dispy – http://dispy.sourceforge.net/ • Parallel Python – http://www.parallelpython.com/ • mpi4py – http://pythonhosted.org/mpi4py/ • OpenMPI – https://www.open-mpi.org/
  93. 93. 参考資料 • Calculations with arrays bigger than your memory (Dask arrays) – http://earthpy.org/dask.html • mpi4py-examplpes – https://github.com/jbornschein/mpi4py-examples • Grok The GIL: How to write fast and thread-safe Python – https://opensource.com/article/17/4/grok-gil • Python 3.5 で実装された async/await を使って軽量スレッドの性能ベンチマーク – http://qiita.com/haminiku/items/0aaf87e9a52ed41b60a7 • Python における非同期処理: asyncio逆引きリファレンス – http://qiita.com/icoxfog417/items/07cbf5110ca82629aca0 • Asynchronous Python – https://hackernoon.com/asynchronous-python-45df84b82434 • THe Open Source Data Science Masters – http://datasciencemasters.org/ • Distributed parallel programming in Python : MPI4PY – https://www.howtoforge.com/tutorial/distributed-parallel-programming-python-mpi4py/ • Awesome Python – https://awesome-python.com/

×