ある種の CUDA を使用して、すべて行列演算である Python コードの高速化を検討しています。現在、私のコードは Python と Numpy を使用しているため、PyCUDA や CudaMat などを使用してコードを書き直すことはそれほど難しくないようです。
しかし、CudaMat を使用した最初の試みで、すべての操作を GPU に保持するために、多くの方程式を再配置する必要があることに気付きました。これには、多くの一時変数の作成が含まれていたため、操作の結果を保存できました。
なぜこれが必要なのかは理解できますが、かつては読みやすかった方程式が、正しいかどうかを調べるのが困難なややこしいものになります。さらに、変換された形式ではない方程式を後で簡単に変更できるようにしたいと考えています。
パッケージ Theano は、最初に操作のシンボリック表現を作成し、次にそれらを CUDA にコンパイルすることでこれを実現しています。しかし、Theano を少し試してみたところ、すべてが不透明であることに不満を感じていました。たとえば、myvar.shape[0] の実際の値を取得するだけでは、かなり後になるまでツリーが評価されないため、困難になります。また、Numpy の代わりに目に見えない形で動作するライブラリにコードが準拠しているフレームワークをあまり好まないでしょう。
したがって、私が本当に欲しいのは、もっと単純なものです。自動微分 (必要に応じて OpenOpt のような他のパッケージがあります)、またはツリーの最適化は必要ありませんが、標準の Numpy 表記から CudaMat/PyCUDA/somethingCUDA への変換だけが必要です。実際、テスト用の CUDA コードなしで Numpy として評価できるようにしたいと考えています。
私は現在、これを自分で書くことを検討していますが、そのようなベンチャーを検討する前に、他の誰かが同様のプロジェクトや良い出発点を知っているかどうかを知りたいと思っていました. これに近い可能性があると私が知っている他のプロジェクトは SymPy だけですが、この目的に適応するのがどれほど簡単かはわかりません。
私の現在の考えは、Numpy.array クラスのように見える配列クラスを作成することです。唯一の機能は、ツリーを構築することです。いつでも、そのシンボリック配列クラスを Numpy 配列クラスに変換して評価できます (1 対 1 のパリティもあります)。あるいは、配列クラスをトラバースして、CudaMat コマンドを生成することもできます。最適化が必要な場合は、その段階で実行できます (たとえば、操作の並べ替え、一時変数の作成など)。何が起こっているのかを調べるのを邪魔することはありません。
ご意見/ご感想/その他 これで大歓迎です!
アップデート
使用例は次のようになります (ここで、sym は理論上のモジュールです)。ここでは、勾配の計算などを行っている可能性があります。
W = sym.array(np.rand(size=(numVisible, numHidden)))
delta_o = -(x - z)
delta_h = sym.dot(delta_o, W)*h*(1.0-h)
grad_W = sym.dot(X.T, delta_h)
この場合、grad_W
実際には、実行する必要のある操作を含む単なるツリーになります。式を通常どおり (つまり Numpy 経由で) 評価したい場合は、次のようにすることができます。
npGrad_W = grad_W.asNumpy()
これは、ツリーが表す Numpy コマンドを実行するだけです。一方、CUDA を使用したい場合は、次のようにします。
cudaGrad_W = grad_W.asCUDA()
これにより、ツリーが CUDA を介して実行できる式に変換されます (これは、いくつかの異なる方法で発生する可能性があります)。
そうすれば、(1) test grad_W.asNumpy() == grad_W.asCUDA()
、および (2) 既存のコードを CUDA を使用するように変換するのは簡単です。