94
Python 分散処理再入門 DB Analytics showcase Sapport 2017 ()HPCソリューションズ 飯坂剛一

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

Embed Size (px)

Citation preview

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

Python 分散処理再入門DB Analytics showcase Sapport 2017

(株)HPCソリューションズ 飯坂剛一

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

今日の話題

• Data処理について • Python での分散処理

– threading / multiprocessing– joblib– dask/distributed– mpi4py

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

今日の話題にしないこと

• Python の文法とか• モジュールやフレームワークの詳細

なんとなく判ったつもりでOK

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

About me

• 飯坂 剛一 (いいさか ごういち)– (株) HPCソリューションズ– [email protected] / [email protected]– 普段は...役務やコンサルタントをしています。

• クラスタシステムの導入や構築• Deep Learning プラットフォームの導入や構築• Open Source の導入と活用方法のコンサルティング

– 好きな言語: Python

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

Data処理

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

たとえばDeepLearningでのデータ処理

• 画像の数が少なければ良い結果が得られない– 多数のデータを収集

• 画像のクラス分類が重要– 対応する画像だけに分類/変換/加工

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

MNIST データ・セット

• 国立標準技術研究所の混合データ セット

• 合計70,000 枚の画像– 学習用60,000 枚– 判別用10,000 枚

• 28x28ピクセル

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

CIFAR-10 データ・セット

• 10カテゴリのデータ・セット• 合計60,00枚のカラー画像

– 学習用50000枚• 各クラス5,000枚

– 判別用10000枚• 各クラス1,000枚

• 32x32ピクセル• PythonのcPickle形式

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

Google Cat

• コンピュータが「猫」がどういうものかを教示されることなく、自力で「猫」を認識できた – 強く反応するニューロンが生まれた

• YouTube にある動画から200x200ピクセルの画像を1000万枚取得

• 1000ノードで3日かけて学習https://googleblog.blogspot.jp/2012/06/using-large-scale-brain-simulations-for.html

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

為替取引: AlpacaAlgo

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

為替取引でのデータ

• 通貨ペアごとのデータを保持– USDJPY, EURUSD, EURJPY, GBPUSD, GBPJPY...

• 各時間単位での売値(Bit), 買値(Ask)の時系列データ– 1M, 1D, 4H, 1H, 30M, 15M, 5M, 1M, Tick

• 各時間単位での売買ボリュームの時系列データ

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

Python

• 低い学習コストと高い可読性• 豊富なライブラリやフレームワーク、アプリケーション

– SciPy, NumPy, Pandas, DASK, Matplotlib, Seaborn, Bokeh– Chainer, Tensorflow, Caffe, Orange3

• データ処理やDeepLearningで楽ができる

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

どのPythonがいいの?• Anaconda Python をお勧めします

– https://www.continuum.io/downloads

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

Orange3: ワークフローツール

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

Python / Jupyter notebook のカバー領域

探索と分析プロジェクトでnotebookのようなアプリやPythonを活用するコラボレーションと公開共有ノートブックやプロジェクトの集中管理、エンタープライズ認証による安全な管理

ディプロイと運用並列フレームワークとリソース管理の統合

アナリスト データサイエンティスト 開発者 データエンジニア DevOps

https://www.continuum.io/anaconda-enterprise-notebooks

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

Conda

• Python 3.6 が使える (Python 2.x, Python 3.x)• x86_64, PowerPC, ARMv7 サポート

– Raspbery Pi2 でも動作する

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

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/

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

Python での分散処理

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

SMP と Cluster

• SMP (Symmetric Multiprocessing)– メモリ共有型並列コンピューティング– 現在はほぼすべてのサーバ、PC、スマートフォンがSMP– 処理はひとつのノード内だけで実行される

• Cluster– 複数のコンピュータをネットワークで結合した並列コンピューティング– 冗長化クラスタ(HAクラスタ)と区別するために

BeoWulf型クラスタやHPCクラスタと呼ばれることもある– 処理は複数のノードで実行される

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

スケールアップとスケールアウト

https://www.idcf.jp/words/scaleup.html

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

スケールアップとスケールアウト

• スケールアップ– 実行させるH/Wを更新することになる– 単一ノード内での並列処理– スレッド

• スケールアウト– H/Wは追加するだけでよい– プログラムをマルチノード対応化が必要– ネットワーク性能も重要になる– マルチプロセス

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

プロセスとスレッド• 各プロセスのメモリは独立• スレッドはプロセスのメモリを共有

https://web.kudpc.kyoto-u.ac.jp/manual/en/parallel

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

Pythonとスレッド

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

PythonでのスレッドとGIL

http://www.tivix.com/blog/lets-go-python/

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

GIL問題の回避方法:その1

• コードを非同期処理で書いてみる (もし可能なら)• 主なモジュール

– gevent– tornado– asyncio

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

非同期処理が向く問題

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

gevent の例: イベントループ

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

tornado の例: コールバック

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

gevent と tornado の比較

• グリーンスレッド– スレッドはハードウェアではなくアプリケーションレベルで制御される– スレッドのようにみえるが、CPUのコンテキストスイッチは起きない– 通常のスレッドプログラミングの問題点はのこる

• コールバック– スレッドプログラミングとは同じようには書けない– スレッド/コルーチンはプラグラマには隠蔽される– 例外は飲み込まれて伝わってこない– コールバックの結果を集められない

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

asyncio の例: (Python 3.5以降のasync/await)

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

asyncio async/await

• CPUコンテキストのスイッチングは起きない– イベントループを使用しアプリケーションレベルでコルーチンを切り替える

• 競合が発生しない– asyncio は1度に1つのコルーチンだけを実行する

• デッドロックにならない– 競合が発生しないのでロックを使用する必要がなく安心

• リソースが欠乏することがない– コルーチンはスレッドで実行されるので余分なソケットやメモリが不要

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

コンテキストスイッチの発生する状況

http://ossforum.jp/node/752

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

GIL問題の回避方法:その2

• マルチプロセスで並列処理をすればよい– ロックを使ってしまうと状況はかわらないことに注意

• 主なモジュール– multiprocessing– joblib– DASK/distributed– mpi4py

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

マルチプロセスでの注意点

• プロセスごとに別々のメモリ領域で動作しているということ– 変数へのアクセスには注意が必要– データ/オブジェクトのやり取りにコツがいる

• プロセス生成とデータ/オブジェクトのコピーのオーバーヘッドがある– やみくもに並列化をせずに、もっとも効果のある部分を並列化– 20/80セオリー:全体の20%の処理が、80%の時間を消費している

• 物理コア数以上のプロセスで実行すると速度向上は期待できない– 並列度が外部に依存していることに注意する

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

multiprocessing モジュール

• スレッドの替りにプロセスを生成してGILを回避– ローカル(SMP)とリモート(Cluster)の両方で並列処理ができる

• threading モジュールと同様のAPI(よく似ている)– start(), run(), join()...

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

joblib モジュール

• タスク出力のディスクキャッシュを再遅延評価• 簡単でシンプルな並列化処理• 実行処理のトラッキングとロギング• 効率的な配列バッファ処理のため大きなnumpy配列が高速• zlibでデータ圧縮してのオブジェクトをpickle/非pickle化

– オブジェクト階層をバイトストリームへの変換と復元

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

他にもいろいろな方法がある

• Python + Spark• Python + Hadoop• Python + RabbitMQ• Python + Elasticsearch

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

jupyter notebook の方がわかりやすいので...

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

DASK dashboard

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

DASK

• コレクション、グラフ、スケジューラで構成• スケールアップとスケールアウト• Out-of-Core 処理

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

コレクション

• Array - NumPy の array と同じインタフェース• DataFrame - Pandas の DataFrame と同じインタフェース• Bag - Python オブジェクトを格納• Delayed - 遅延評価

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

Array

import numpy as npf = h5py.File('myfile.hdf5')x = np.array(f['/small-data'])x - x.mean(axis=1)

import dask.array as daf = h5py.File('myfile.hdf5')x = da.from_array(f['/big-data'], chunks=(1000, 1000)) x - x.mean(axis=1).compute()

• NumPyと同じように使える

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

DataFrame

import pandas as pd dd.read_csv('2015-*-*.csv')df.groupby(df.user_id).value.mean()

import dask.dataframe as dddf = dd.read_csv('2015-*-*.csv')df.groupby(df.user_id).value.mean().compute()

• Pandas と同じように使える

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

グラフ

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

スケジューリング

• SMPとクラスタの両方をサポート– 単一ノードでのスケールアップ– クラスタでのスケールアウト

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

クラスタの作成

• 準備: 各ノードで distibuted のインストール$ conda create -y -n demo$ source activate demo(demo) $ conda install bokeh(demo) $ conda install distributed

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

スケジューラの起動

(demo) $ dask-schudler dask-schedulerdistributed.scheduler - INFO - -----------------------------------------------distributed.scheduler - INFO - Scheduler at: 159.203.166.31:8786distributed.scheduler - INFO - http at: 159.203.166.31:9786distributed.scheduler - INFO - bokeh at: 159.203.166.31:8788distributed.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

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

ワーカーの起動

• スケジューラの"ホスト:ポート"を引数として与える(demo) $ dask-worker 159.203.166.31:8786 --memory-limit=autodistributed.nanny - INFO - Start Nanny at: 138.197.11.22:36452distributed.worker - INFO - Start worker at: 138.197.11.22:39702distributed.worker - INFO - nanny at: 138.197.11.22:36452distributed.worker - INFO - http at: 138.197.11.22:34241distributed.worker - INFO - bokeh at: 138.197.11.22:8789distributed.worker - INFO - Waiting to connect to: 159.203.166.31:8786distributed.worker - INFO - -------------------------------------------------distributed.worker - INFO - Threads: 2distributed.worker - INFO - Memory: 2.49 GBdistributed.worker - INFO - Local Directory: /tmp/nanny-xk59hltvdistributed.worker - INFO - -------------------------------------------------

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

クラスタの作成 (共有ファイルシステムを使う場合)

• スケジューラの起動

• ワーカーの起動

$ dask-scheduler --scheduler-file /path/to/scheduler.json

$ dask-worker --scheduler-file /path/to/scheduler.json

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

クラスタの作成 (Python API)

• プログラムの中からスケジューラを起動from distributed import Schedulerfrom tornado.ioloop import IOLoopfrom threading import Thread

loop = IOLoop.current()t = Thread(target=loop.start, daemon=True)t.start()

s = Scheduler(loop=loop)s.start('tcp://:8786')

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

クラスタの作成 (Python API)

• プログラムの中からワーカーを起動from distributed import Workerfrom tornado.ioloop import IOLoopfrom 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()

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

タスクの実行

• スケジューラの"ホスト:ポート"を与える

from dask.distributed import Clientclient = 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})

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

Ansible で実行環境を構築すると楽

• プレイブックで簡単にスケールアウト

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

jupyter notebook の方がわかりやすいので...

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

Blaze

• 異なるストレージシステムを抽象化してくれる– http://blaze.pydata.org/en/latest

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

odo

• 簡単にデータ変換してくれる– http://odo.pydata.org/en/latest/

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

MPI(Message Passing Interface)

• 並列処理をするための標準化された規格

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

MPI

• MPI_ではじまる関数や定数• MPI_Init() と MPI_Finalize() に囲む

– この中でMPI関数を呼び出させる• MPIプログラムで生成される各プロセスはランクという値が設定される

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

MPI: Hello World in C

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

mpi4py: Hello World in Python

#!/usr/bin/env python

from mpi4py import MPIimport 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))

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

Hello World 実行方法

$ mpicc -o helloworld.exe helloworld.c$ mpiexec -n 4 helloworld.exe

プロセス数の指定

$ mpiexec -n 4 python helloworld.py

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

conda を使うときは...

• システム側の python と混乱しやすい• module コマンドで環境をロードするようにするとよい

– http://modules.sourceforge.net/– 例: module load conda

• conda 環境を作っていればアクティベートを忘れやすい– 例: source activate demo

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

mpi4py: HelloWorld - broadcast

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

mpi4py: HelloWorld - P2P (Send/Recv)

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

mpi4py: 集計 - P2P (Send/Recv)

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

Send/Recvの動作イメージ

https://www.nesi.org.nz/sites/default/files/mpi-in-python.pdf

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

mpi4py: 集計 - reduce

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

mpi4py: reduce の動作イメージ

https://www.nesi.org.nz/sites/default/files/mpi-in-python.pdf

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

画像処理: ノイズ除去シリアル版import numpy as npfrom skimage import data, img_as_floatfrom skimage.filter import denoise_bilateralimport skimage.ioimport os.pathimport time

curPath = os.path.abspath(os.path.curdir)noisyDir = os.path.join(curPath,'noisy')denoisedDir = os.path.join(curPath,'denoised')

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

画像処理: ノイズ除去シリアル版 (続き)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()

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

画像処理: ノイズ除去MPI版

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

画像処理: ノイズ除去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))

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

画像処理: ノイズ除去MPI版 (続き)

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

jupyter notebook の方がわかりやすいので...

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

GPGPU

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

GPGPUで使われるコンポーネント

• NVIDIA CUDA– CuPY (Chainer)– PyCUDA– pygpu

• cuDNN - DeepLearning ライブラリ• NCCL - マルチGPUを効率的に処理させる• CUDA-aware MPI

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

CUDA-aware MPI

• 対応するオープンソースのMPI実装– MVAPICH2 1.8以降– OpenMPI 1.7以降

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

通常のMPIでのデータ送受信

• ホスト上のメモリへのポインタのみがMPIに渡される。 • cudaMemcpyを使用してGPUバッファをホストメモリ経由で

ステージングする必要がある。//MPI rank 0cudaMemcpy(s_buf_h,s_buf_d,size,cudaMemcpyDeviceToHost);MPI_Send(s_buf_h,size,MPI_CHAR,1,100,MPI_COMM_WORLD);

//MPI rank 1MPI_Recv(r_buf_h,size,MPI_CHAR,0,100,MPI_COMM_WORLD, &status);cudaMemcpy(r_buf_d,r_buf_h,size,cudaMemcpyHostToDevice);

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

CuDA-aware MPIでのデータ送受信

• CuDA-aware MPIでは cudaMemcpy() が不要。

//MPI rank 0MPI_Send(s_buf_d,size,MPI_CHAR,1,100,MPI_COMM_WORLD);

//MPI rank n-1MPI_Recv(r_buf_d,size,MPI_CHAR,0,100,MPI_COMM_WORLD, &status);

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

性能比較

https://devblogs.nvidia.com/parallelforall/benchmarking-cuda-aware-mpi/

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

UVA(Unified Virtual Addressing)

• GPUとホストのメモリを単一仮想アドレス空間に統合

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

GPUDirect RDMA

• GPUのメモリ上のデータをホストのメモリを介さずにNICに直接送信

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

GPUDirect P2P

• 同じノード内の2つのGPUのメモリ間でバッファを直接コピーする

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

通常のMPIでのデータの流れ

GPUメモリ GPUメモリ

Host Buffer Host Buffer

• 2つのGPUのメモリ間に複数のバッファがあり、それぞれコピーする

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

通常のMPIでのデータの流れ• それぞれのバッファでのコピーだけ時間がかかる

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

CUDA-aware MPI / GPUDirect P2P

GPUメモリ GPUメモリ

Host Buffer Host Buffer

• 同じシステム内の2つのGPUのメモリ間では直接コピーする

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

CUDA-aware MPI / GPUDirect RDMA

GPUメモリ GPUメモリ

Host Buffer Host Buffer

• 他ノードのGPUのメモリ間ではホストのメモリを経由せずにコピー

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

CUDA-aware MPIでのデータの流れ

• バッファへのメモリ転送が不要なので処理速度が向上する

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

おまけ

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

HPCソリューションズ HPCS-DLD

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

HPCS-DLD

• Anaconda Python をベースにDeepLearningのフレームワークやライブラリ、ミドルウェアをパッケージングしたソフトウェアディストリビューション

• それぞれのオープンソース・ライセンスに準じて無償で使用することができます。

– http://www.hpc-sol.co.jp/dld/ • サブスクリプション契約をするとアップディトレポジトリへのアクセスと

アップディトリクエストが可能になります。

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

参考資料• 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/

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

参考資料• 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/