Hu Yuanming: 「太極拳」ライブラリをインポートして、Python コードを 100 倍高速化します。

この記事は Qubit からの転載です。

Fengse は凹型非 Si 量子ビットから送信されます
| パブリック アカウント QbitAI

Python のシンプルさと読みやすさはパフォーマンスを犠牲にしていることを誰もが知っています—

特に複数の for ループなど、計算量が多い場合に発生します。

しかし今、ボスの胡遠明氏はこう言った。

「Taichi」というライブラリをインポートするだけで、コードを100 倍高速化できます。

0581b86ea05a6fab054daabcd4e4ac25.png

信じないで?

3 つの例を見てみましょう。

素数の数を計算する、速度 x 120

最初の例は非常に単純で、指定された正の整数 N より小さい素数をすべて検索します。

標準的な答えは次のとおりです。

e65401e0cd358051ed718057cd787020.png

上記のコードを保存して実行します。

N が 100 万の場合、結果を取得するまでに 2.235 秒かかります。

e9357a1d3e1c66fcfd45ab04652572ae.png

さあ、魔法をかけてみましょう。

関数本体を変更せずに、「taichi」ライブラリをインポートし、2 つのデコレータを追加します。

9f8fd9ab1a3f50bf02ca779e02e60780.png

ビンゴ!同じ結果を得るのにかかる時間はわずか 0.363 秒で、ほぼ 6 倍速くなります。

64ce41c2ab66e22f4e57efa1f07775b6.png

N=1,000 万の場合、所要時間はわずか 0.8 秒ですが、N=1,000 万の場合は 55 秒かかり、70 倍速くなります。

それだけでなく、ti.init() から ti.init(arch=ti.gpu) にパラメータを追加して、taich がGPU上で計算を実行できるようにすることもできます。

現時点では、1,000 万未満のすべての素数を計算するのにかかる時間はわずか 0.45 秒で、これは元の Python コードよりも120 倍高速です。

すごいですか?

何?この例は単純すぎて説得力がないと思いますか? もう少し複雑なものを見てみましょう。

ダイナミック プログラミング、速度 x500

言うまでもなく、動的計画法は最適化アルゴリズムであり、途中の計算結果を動的に保存することで計算時間を短縮します。

古典的な教科書「アルゴリズム入門」に掲載されている古典的な動的計画問題「最長共通部分列問題 (LCS)」を例に挙げてみましょう。

たとえば、シーケンス a = [0, 1, 0, 2, 4, 3, 1, 2, 1] およびシーケンス b = [4, 0, 1, 4, 5, 3, 1, 2] の場合、それらの LCSは:

LCS(a, b) = [0, 1, 4, 3, 1, 2]。

動的計画法の考え方による LCS の計算は、まずシーケンス a の最初の i 要素とシーケンス b の最初の j 要素の最長の共通部分列の長さを解き、次に i または j の値を徐々に増やしていくことを繰り返します。プロセスを経て、結果が得られます。

この部分列の長さを参照するには f[i, j] を使用します。つまり、LCS((prefix(a, i), prefix(b, j) です。そのうち、prefix(a, i) は最初の i を表します。シーケンス a の要素、つまり a[0]、a[1]、...、a[i - 1] を使用すると、次の漸化関係が得られます。

6ded319769ef349862dfcfd50c63b6bf.png

完全なコードは次のとおりです。

a41a129625573060e2c13bfe0ce5456a.png

ここで、Taichi を使用して高速化します。

2f7659b07ea9082be62aa7b110b8fb68.png

結果は次のとおりです。

68e3a613d57aae4bff8418eb598349a8.png

Hu Yuanming のコンピュータのプログラムは最速で 0.9 秒以内に完了しますが、NumPy での実装には 476 秒かかり、その差は 500 倍以上です。

最後に、別の例を見てみましょう。

驚くべき効果をもたらす反応拡散方程式

自然界には、無秩序に見えるが完全にランダムではないパターンを持つ動物が常に存在します。

6f9cb69426c92e92a02fd9a768470009.png

チューリング マシンの発明者であるアラン チューリングは、この現象を説明するモデルを最初に考案しました。

このモデルでは、パターン生成をシミュレートするために 2 つの化学物質 (U と V) が使用されます。これら 2 つの関係は獲物と捕食者に似ており、自ら移動し相互作用します。

  1. 最初に、U と V はドメイン全体にランダムに分散されます。

  2. 各時間ステップで、それらは隣接する空間に徐々に拡散します。

  3. UとVが出会うと、Uの一部がVに飲み込まれます。したがって、V の濃度が増加します。

  4. U が V によって消去されるのを避けるために、各タイム ステップで U の一定の割合 (f) を追加し、V の一定の割合 (k) を削除します。

上記のプロセスは「反応拡散方程式」として概説されます。

750d2d0635de1fe17a3f77e51585c9d6.png

重要なパラメータは 4 つあります。Du ( U の拡散速度)、D v (V の拡散速度)、f (feed の略語で、U の添加を制御します)、k (kill の略語で、U の添加を制御します) Vの削除)。

この方程式を Taichi で実装する場合、まずドメインを表すグリッドを作成し、vec2 を使用して各グリッド内の U、V 濃度値を表します。

ラプラシアン値の計算には、隣接するグリッドへのアクセスが必要です。同じループ内でデータの更新と読み取りを避けるには、W×H×2 の同じ形状の 2 つのグリッドを作成する必要があります。

あるグリッドからデータにアクセスするたびに、更新されたデータを別のグリッドに書き込み、次のグリッドに切り替えます。データ構造の設計は次のようになります。

7a35020556b71a805ac539f36cb1b6f8.png

最初に、グリッド内の U の濃度を 1 に設定し、ランダムに選択された 50 個の位置に V を配置します。

36b8cc1da05fa0578df084dca0275dc3.png

実際の計算は 10 行未満のコードで実行できます。

@ti.kernel
def compute(phase: int):
    for i, j in ti.ndrange(W, H):
        cen = uv[phase, i, j]
        lapl = uv[phase, i + 1, j] + uv[phase, i, j + 1] + uv[phase, i - 1, j] + uv[phase, i, j - 1] - 4.0 * cen
        du = Du * lapl[0] - cen[0] * cen[1] * cen[1] + feed * (1 - cen[0])
        dv = Dv * lapl[1] + cen[0] * cen[1] * cen[1] - (feed + kill) * cen[1]
        val = cen + 0.5 * tm.vec2(du, dv)
        uv[1 - phase, i, j] = val

ここでは、整数フェーズ (0 または 1) を使用して、どのグリッドからデータを読み取るかを制御します。

最後のステップは、V の濃度に応じて結果を色付けすることです。これにより、このような素晴らしいパターンが得られます。

aec8a98c46ea550e762a9a1c57d600e5.gif

興味深いことに、Hu Yuanming 氏は、V の初期濃度がランダムに設定された場合でも、毎回同様の結果が得られることを紹介しました。

また、Numba 実装では 30fps 程度しか達成できませんが、Taichi 実装ではバックエンドとして GPU を選択できるため、簡単に 300fps を超えることができます。

インストールするには pip install

上記の 3 つの例を読んで、今信じられますか?

実際、Taichi は Python に組み込まれた DSL (Dynamic Sc​​ripting Language) であり、独自のコンパイラーを使用して、@ti.kernel によって装飾された関数を CPU や GPU を含むさまざまなハードウェアにコンパイルし、ハイパフォーマンス コンピューティングを実行します。

これにより、C++/CUDA のパフォーマンスをうらやむ必要はなくなります。

名前が示すように、Taichi は Taichi Graphics Hu Yuanming のチームから来ています。これで、pip install を使用するだけでこのライブラリをインストールし、NumPy、Matplotlib、PyTorch などの他の Python ライブラリと対話できます。

もちろん、Taichi とこれらのライブラリや他の高速化手法との違いは何ですか? Hu Yuanming 氏も長所と短所を詳細に比較しました。興味のある方は下のリンクをクリックして詳細をご覧ください:

https://docs.taichi-lang.org/blog/accelerate-python-code-100x

おすすめ

転載: blog.csdn.net/u014333051/article/details/126844632