この記事は、The Parallel Universe Magazine 57 号に掲載されている「Accelerate Simulations and Backpropagation with Python* and C++ Analytics」の日本語参考訳です。原文は更新される可能性があります。原文と翻訳文の内容が異なる場合は原文を優先してください。
AADC (Algorithmic Adjoint Differentiation Compiler、自動随伴微分コンパイラー) は、計算最適化の最前線に立っています。元々は、計算集約型タスクを効率良く処理できることから C++ 向けに設計されましたが、現在では当初の目的を超えて、ハイパフォーマンス・コンピューティングを必要とするシミュレーションや推論タスクなど、幅広いアプリケーションを高速化しています。演算子のオーバーロードを使用して有向非巡回グラフ (DAG) を効果的に抽出する AADC は、計算グラフが膨大な数のノードで構成される環境で優れた性能を発揮します。高密度テンソル演算を処理する一般的なマシンラーニング (ML) やディープ・ニューラル・ネットワーク・フレームワークとは異なり、AADC は主にスカラー演算で構成される非常に大規模な計算グラフを迅速にコンパイルすることに特化しており、複雑で大量の計算を迅速に処理する必要があるドメインに不可欠なツールです。
特に Python* では、主に ML およびディープラーニング (DL) アプリケーションのニーズによって計算ツールが形成されてきました。これらのアプリケーションは、テンソル演算の処理に優れたフレームワークを中心としています。代表的な例として、ニューラル・ネットワーク計算を処理する TensorFlow* や PyTorch* などがあります。ただし、主要なドメイン以外に適用する場合、これらのフレームワークには固有の制限があります。その 1 つは、メモリー内に完全な DAG を格納する必要があることです。
多くの計算タスク、特に金融におけるシミュレーションや随伴微分法を含むタスクでは、大きなグラフを素早くコンパイルする能力がパフォーマンスに直接影響します。これらのコンテキストでは、ジャストインタイム (JIT) コンパイルが重要になりますが、JIT の利点は、コンパイルが高速でなければ十分に発揮されません。コンパイルが遅いと、JIT によってもたらされるはずのランタイム・パフォーマンスの向上が打ち消される可能性があります。
AADC アーキテクチャー
AADC は、ストリーミング・グラフ・コンパイラー・フレームワークを実装することで、高性能な計算タスクの厳しいニーズを満たすように設計されています。この革新的なアーキテクチャーは、ユーザープログラムの実行時に x64 インテル® AVX2/インテル® AVX-512 マシンコード命令を動的に生成することで機能します。このメカニズムは、ベクトル化されたカーネルをコンパイルして、入力から出力までユーザー関数を複製するだけでなく、随伴または後方伝播も管理します。これにより、AADC は小さなメモリー・フットプリントを維持しながら、高いパフォーマンスを実現できます。図 1 はこれを図解したものです。
図 1. AADC
AADC 設計の中核は、基本操作を直接トレースし、プログラムの実行時にマシンレベルの命令に再コンパイルする機能です。このプロセスにより、高レベルのプログラミング言語の非効率性が排除されます。操作を x64 マシンコードに直接変換することで、AADC はマルチスレッド、インテル® AVX2、インテル® AVX-512 などの最新のプロセッサー機能を活用して、計算タスクを最大限の効率で実行できます。
AADC の重要なアーキテクチャー上の利点は、高度なコード折り畳みおよび圧縮技術です。従来の自動微分ツールは、大量の中間データを格納する必要があるため、メモリー使用量が大きくなりがちです。これに対し、AADC は高度なアルゴリズムを使用して、計算グラフと中間結果の格納に必要なメモリーを最小限に抑えます。これは、コードをインテリジェントに折り畳み、圧縮することで実現され、メモリー要件が軽減されるだけでなく、計算中に処理および移動するデータ量が軽減されるため、実行速度が向上します。
AADC は、C++ と Python* の両方の分析で計算をトレースする「アクティブタイプ」を採用し、さまざまなプログラミング環境間で計算操作の一貫した正確な記録を維持します。これにより、すべての計算が、言語に関係なくキャプチャーされ、最適化されます。ユーザーは、トレースをトリガーし、入力データの 1 つのインスタンスで JIT コンパイルを使用することで、このプロセスを開始します。コンパイルされた DAG は、複数のサンプルを処理するカーネルとして機能し、高レベルのプログラミング構造のオーバーヘッドなしで、低レベルのマシンコード速度で実行されます。