レビュー:NvidiaのRapidsはPython分析をGPUにもたらします

機械学習モデルの構築は反復的なプロセスです。多くの場合、これは「サイクルの勝利で最速」のゲームです。反復できる速度が速いほど、新しい理論を探索して良い答えを得るのが簡単になります。これが、今日のAIの実際の企業での使用が、問題に莫大なリソースを投入する可能性のある最大の企業によって支配されている理由の1つです。

Rapidsは、Nvidiaによってインキュベートされたいくつかのオープンソースプロジェクトの傘であり、処理パイプライン全体をGPUに配置し、I / Oバウンドデータ転送を排除すると同時に、個々のステップの速度を大幅に向上させます。また、データの共通フォーマットを提供し、異種システム間でデータを交換する負担を軽減します。ユーザーレベルでは、RapidsはPython APIを模倣して、そのユーザーベースの移行を容易にします。

Tidyverseクックブック

Rapidsエコシステムアーキテクチャ

Rapidsプロジェクトは、ほとんどの場合、Pythonの機械学習およびデータ分析APIを複製することを目的としていますが、CPUではなくGPUを対象としています。つまり、Python開発者は、CUDAプログラミングや並列操作の低レベルの詳細を学ぶ必要なしに、GPUで実行するために必要なすべてのものをすでに持っているということです。 Pythonistasは、GPUに対応していないマシンでコードを開発し、いくつかの調整を加えるだけで、使用可能なすべてのGPUでコードを実行できます。

Nvidia CUDAツールキットは、数学ライブラリ、並列アルゴリズム、およびグラフ分析用の低レベルのプリミティブを提供します。アーキテクチャの中心にあるのは、Apache Arrowに基づくGPUデータフレームであり、プログラミング言語に依存しない列状のメモリ内データ構造を提供します。ユーザーは、cuDFおよびPandasのようなAPIを介してGPUデータフレームと対話します。並列計算用のPythonライブラリであるDaskは、アップストリームのPython APIを模倣し、並列計算用のCUDAライブラリと連携します。DaskをPython用のSparkと考えてください。

急流

cuDF、cuML、cuGraphの3つの主要なプロジェクトは独立して開発されていますが、シームレスに連携するように設計されています。プロジェクトの一環として、より広範なPythonエコシステムへのブリッジも開発されています。

Rapidsのインストール

AWSのLinuxマシンへのAnacondaを介したインストールは、バージョン0.11での依存関係の変更によるいくつかの問題を除いて、ほとんど簡単でした。libcudfを使用するためのC / C ++ライブラリのインストールはそれほど簡単ではなかったので、PythonAPIとCondaのインストールプロセスに固執することをお勧めします。RapidsにはJupyterノートブックが含まれており、Googleの無料のColabでも入手できるため、簡単に始めることができます。Jupyterノートブックバージョン0.10を使用して、Nvidia Tesla T4GPUを含むGoogleColabでコードを実行しました。

RapidsのGPUデータフレーム

データサイエンスワークフローの中心はデータフレームです。ここで機能エンジニアリングが行われ、データサイエンティストがダーティデータを処理するため、大部分の時間が費やされます。cuDFは、GPUベースのパンダのようなデータフレーム用のRapidsプロジェクトです。cuDFの基盤となるのはlibcudfです。これは、Apache Arrowデータのインポート、配列での要素ごとの数学の実行、GPU内メモリマトリックスでの並べ替え、結合、グループ化、縮小などの操作を実行するための低レベルプリミティブを実装するC ++ライブラリです。libcudfの基本的なデータ構造はGPUDataFrame(GDF)であり、これはApacheArrowの列指向データストアでモデル化されています。

急流

Rapids Pythonライブラリは、Pandasのようなデータフレームに似た高レベルのインターフェイスをユーザーに提供します。多くの場合、PandasコードはcuDFで変更されずに実行されます。そうでない場合、通常は小さな変更のみが必要です。

cuDFのユーザー定義関数

基本的なデータ操作を終えたら、ユーザー定義関数(UDF)を使用して行と列を処理する必要がある場合があります。cuDFは、配列、シリーズ、移動ウィンドウなど、よりコースグレインのデータ構造を処理するコードを記述するためのPyDataスタイルのAPIを提供します。現在、数値型とブール型のみがサポートされています。UDFは、LLVMのサブセットを使用して数値関数をCUDAマシンコードにコンパイルするNumbaJITコンパイラーを使用してコンパイルされます。これにより、GPUでの実行時間が大幅に短縮されます。

cuDFの文字列

GPUはフロートベクトルを迅速に処理するのに最適ですが、通常は文字列データの処理には使用されていません。実際には、ほとんどのデータは文字列の形式で提供されます。cuStringsは、文字列の配列内のトークンの分割、適用、連結、トークンの置換などを行うためのGPU文字列操作ライブラリです。cuDFの他の関数と同様に、C / C ++ライブラリ(libnvStrings)として実装され、パンダを模倣するように設計されたPythonレイヤーによってラップされます。文字列データ型はGPUでの実行用に最適化されていませんが、コードの並列実行により、CPUベースの文字列操作よりも高速化されるはずです。

cuDFにデータを出し入れする

データフレームI / Oは、専用ライブラリcuIOによって処理されます。 Arrow、ORC、Parquet、HDF5、CSVなど、最も一般的に使用される形式がすべてサポートされています。幸運にもDGX-2ハードウェアで実行できる場合は、GPUダイレクトストレージ統合を使用して、CPUを使用せずにデータを高速ストレージからGPUに直接移動できます。致命的なユーザーは、大規模なデータセットを解凍するときにGPUが提供するスピードアップと、Pythonエコシステムとの緊密な統合を引き続き評価します。

GPU Direct Storageは現在アルファ版であり、リリースされるとほとんどのTeslaGPUで利用できるようになります。NumPy配列、Pandas DataFrames、およびPyArrowテーブルからGPUデータフレームを1行のコードで作成できます。他のプロジェクトは__cuda_array_interface__、Numbaエコシステム内にあるライブラリを介してデータを交換できます。ニューラルネットワークライブラリ用のDLPackもサポートされているインターフェイスです。

おそらく、cuDFを使用する際の最大の欠点は、Pythonの外部での相互運用性の欠如です。Arrowが行ったように、C / C ++ APIの強力な基盤に焦点を当てることで、より広範なエコシステムが可能になり、プロジェクト全体にメリットがもたらされると思います。

ラピッズのcuML

cuMLが表明した目標は、「PythonのScikit-GPUを利用した学習」です。理論的には、これは、インポートステートメントを変更し、CPUでの実行の違いを説明するためにいくつかのパラメーターを調整するだけでよいことを意味します。場合によっては、ブルートフォースアプローチの方が適しています。GPUベースのScikit-learnを使用することの利点は、過小評価することはできません。スピードアップはかなりのものであり、データアナリストは何倍も生産性を高めることができます。C ++ APIは、Pythonバインディング以外で広く使用する準備が整っていませんが、これは改善されると予想されます。

cuMLには、複数のノード間でPythonをスケーリングするためのライブラリであるDaskを介したハイパーパラメータ調整を支援するためのAPIも含まれています。多くの機械学習アルゴリズムを効果的に並列化でき、cuMLはマルチGPUアルゴリズムとマルチノードマルチGPUアルゴリズムの両方を積極的に開発しています。

急流

ラピッズのcuGraph

cuGraphはRapidsエコシステムの3番目のメンバーであり、他のメンバーと同様に、cuGraphはcuDFおよびcuMLと完全に統合されています。グラフアルゴリズム、プリミティブ、ユーティリティの優れた選択肢を提供し、すべてGPUで高速化されたパフォーマンスを備えています。cuGraphでのAPIの選択は、Rapidsの他の部分よりもいくらか広範囲であり、NetworkX、Pregel、GraphBLAS、およびGQL(グラフクエリ言語)がすべて利用可能です。

急流

cuGraphは、cuMLというよりも精神的にはツールキットのようなものです。グラフ技術は、学界と産業界の両方で動きの速い空間です。したがって、設計上、cuGraphは開発者にC ++レイヤーとグラフプリミティブへのアクセスを提供し、サードパーティがcuGraphを使用して製品を開発することを奨励します。いくつかの大学が貢献しており、Texas A&M(GraphBLAS)、Georgia Tech(Hornet)、およびUC Davis(Gunrock)のプロジェクトが「製品化」され、cuGraphの傘下に含まれています。各プロジェクトは、すべてGPUで高速化され、すべて同じcuDFデータフレームに支えられた異なる機能セットを提供します。

NetworkXは、Rapidsチームがネイティブインターフェイスを対象としているPythonAPIです。そのインターフェースを介して利用可能なアルゴリズムは多数あります。マルチGPUはページランクのみですが、チームは、該当する場合、他のマルチGPUバージョンに積極的に取り組んでいます。

急流

私が興味深いと思ったcuGraphサブプロジェクトの1つは、線形代数の言語でグラフアルゴリズムのビルディングブロックを標準化する取り組みであるcugraphBLASです。GraphBLAS(graphblas.org)に基づいており、スパース動的グラフ処理用に設計されたカスタムデータ構造です。

別のcuGraphサブプロジェクトであるHornetは、グラフデータを含めるためのシステムに依存しない形式を提供します。これは、Apachearrowがシステムに依存しない方法でデータフレームを処理する方法に類似しています。Hornetは、SNAP、mtx、metis、edgesなどの一般的なグラフ形式のほとんどをサポートしています。

Pythonコミュニティに近いという精神に沿って、PythonのネイティブNetworkXパッケージを複雑なネットワークの研究に使用できます。これには、グラフとマルチグラフのデータ構造が含まれ、CUDAプリミティブを使用して再実装され、標準のグラフアルゴリズムの多くを再利用し、ネットワーク構造と分析測定を実行できます。アルゴリズムの大部分は、NetworkXのようなシングルGPUです。それでも、GPUのみで実行すると、大幅な高速化が実現し、作業は引き続きマルチGPU実装に移行します。

Rapidsロードマップについて 

GPUベースの分析が提供する驚異的なスピードアップを考えると、将来のバージョンでいくつかの新しいプロジェクトが混在するようになります。

ディープラーニング用のDLPackとarray_interface

多層ニューラルネットワークはGPUに移行された最初のワークロードの1つであり、この機械学習のユースケースにはかなりの量のコードが存在します。以前は、DLPackはディープラーニングライブラリ間のデータ交換の事実上の標準でした。現在、array_interfaceは一般的にサポートされています。Rapidsは両方をサポートしています。

cuSignal

Rapidsの他のほとんどのプロジェクトと同様に、cuSignalは既存のPythonライブラリ(この場合はSciPy Signalライブラリ)のGPUアクセラレーションバージョンです。オリジナルのSciPySignalライブラリはNumPyに基づいており、GPUで高速化された同等のcuSignalのCuPyに置き換えられています。これは、Rapidsの設計哲学が機能している良い例です。いくつかのカスタムCUDAカーネルを除いて、GPUへの移植には、ほとんどの場合、インポートステートメントの置き換えといくつかの関数パラメーターの調整が含まれます。 

信号処理をRapidsフォールドに取り入れることは、賢明な方法です。信号処理はいたるところにあり、産業や防衛ですぐに役立つ多くの商用アプリケーションがあります。

cuSpatial

時空間操作はGPUアクセラレーションの優れた候補であり、トラフィックパターン、土壌の健康/品質、洪水リスクの分析など、日常生活で直面する多くの現実の問題を解決します。ドローンを含むモバイルデバイスによって収集されたデータの多くには地理空間コンポーネントがあり、空間分析はスマートシティの中心です。 

他のコンポーネントと同様に設計されたcuSpatialは、CUDAプリミティブと推力ベクトル処理ライブラリに基づいて構築されたC ++ライブラリであり、データ交換にcuDFを使用します。C ++ライブラリの利用者は、C ++リーダーを使用して、ポイント、ポリライン、およびポリゴンのデータを読み取ることができます。Pythonユーザーは、ShapelyやFionaなどの既存のPythonパッケージを使用してNumPy配列を埋めてから、cuSpatial Python APIを使用するか、cuDFデータフレームに変換することをお勧めします。 

データ視覚化のためのcuxfilter

データの視覚化は、分析ワークフロー内でも、結果の表示またはレポート作成でも基本です。しかし、GPUがデータ自体を処理できるすべての魔法にとって、そのデータをブラウザーに出力することは簡単な作業ではありません。 Crossfilter JavaScriptライブラリに触発されたcuxfilterは、サードパーティの視覚化ライブラリがcuDFデータフレームにデータを表示できるようにするスタックを提供することにより、そのギャップを埋めることを目的としています。

チームが最適なアーキテクチャとコネクタパターンを分類する際に、cuxfilterが数回繰り返されました。最新のイテレーションでは、Jupyterノートブック、Bokehサーバー、およびPyVizパネルを活用していますが、統合実験には、Uber、Falcon、およびPyDeckのプロジェクトが含まれています。このコンポーネントはまだプライムタイムの準備ができていませんが、Rapids0.13でリリースされる予定です。可動部品がたくさんあり、私はそれを直接実験することはできませんでしたが、それがその約束を果たしていれば、これはRapidsツールキットへの素晴らしい追加になるでしょう。

Daskでスケールアップおよびスケールアウト

DaskはPythonの分散タスクスケジューラであり、ApacheSparkがScalaで果たすのと同様の役割をPythonで果たします。Dask-cuDFは、パーティション化されたGPUベースのデータフレームを提供するライブラリです。Dask-cuDFは、cuMLの使用を計画している場合、またはGPUメモリよりも大きいデータセットや複数のファイルに分散しているデータセットをロードする場合に適しています。

Spark RDD(Resilient Distributed Dataset)と同様に、Dask-cuDF分散データフレームはほとんどローカルマシンと同じように動作するため、スケールアップが必要な場合は、ローカルマシンを試して、分散モデルに移行できます。Dask-cuMLはcuMLマルチノード機能を提供するため、DGXワークステーションの予算がない場合に適したオプションになります。