対応する演算が90%でも、全部対応の場合の6.2倍かかりました。
残り10%が標準の実行役へ回るたびに、受け渡しの手間が乗るためです。
モデルは実行役ごとの部分に分けられます。対応しない部分が残るたびに、受け渡しの手間が乗ります。
ONNX Runtimeは、モデルを機材ごとの部分に分けます。公式はモデルの計算図にいくつもの最適化を適用したあと、使える機材ごとの高速化装置に基づいて部分図へ分割すると述べています。
分けた先が対応していない場合、何が起きるのか。実際に流して数えました。
演算 240個の並び。速い実行役は1個 4μs、対応していないと 210μs
実行役をまたぐたびに 35μs の受け渡しがかかる
対応する割合 対応する演算 切り替わった回数 合計時間 全部対応の場合との比
100% 240個 0回 960μs 1.0倍
90% 222個 36回 5928μs 6.2倍
70% 183個 92回 15922μs 16.6倍
50% 136個 122回 26654μs 27.8倍
20% 53個 90回 42632μs 44.4倍
0% 0個 0回 50400μs 52.5倍
対応が90%でも6.2倍です。残り10%だけで、時間の大半を使っています。
対応していない演算1個は210μsで、対応している演算52.5個ぶんに相当します。少数でも重く効きます。
切り替わった回数を見ると、90%では36回、50%では122回です。境界をまたぐたびに35μsが乗ります。
対応していない演算がまとまっていれば、切り替わりは少なくて済みます。割合だけでなく、並び方も効きます。
この境界の重さはllama.cppの記事で見た、遅い側に残った層の効き方と同じ形です。
対応が10%欠けるだけで、時間は大きく跳ねる。
ONNX Runtime applies a number of graph optimizations on the model graph then partitions it into subgraphs based on available hardware-specific accelerators.原文ONNX Runtime 公式ドキュメント「Get Started」 この内容の有効期限2027-02-18
実行役は複数を組み合わせられます。優先順位の並べ方だけで、同じ演算でも時間が変わります。
ONNX Runtimeでは、各部分がそれぞれの実行役から加速を受けます。公式は核となるONNX Runtimeの最適化された計算に加えて、割り当てられた部分図はそれぞれの実行役からさらなる高速化を受けると述べています。
実行役は複数あり、順番に試されます。順序を変えるとどうなるのか実際に流して数えました。
演算 200個。実行役ごとに対応できる演算の割合と1個あたりの時間が違う 優先順位のリストを先頭から試し、最初に対応できた実行役で処理する 優先順位 合計時間 使われた実行役の内訳 専用の速い実行役→汎用の速い実行役→標準の実行役 2235μs 専用の速い実行役98/汎用の速い実行役69/標準の実行役33 汎用の速い実行役→専用の速い実行役→標準の実行役 2823μs 汎用の速い実行役167/標準の実行役33 標準の実行役 8000μs 標準の実行役200
専用の実行役を先に試すと2,235μsです。標準だけなら8,000μsで、3.6倍の差があります。
専用を先にするか汎用を先にするかでも、2,235μsと2,823μsで26%違いました。
専用の実行役は対応範囲が狭い代わりに1個3μsと速く、汎用は範囲が広い代わりに9μsです。狭くて速いものを先に置くと、外れた分だけ次に回せます。
順序を逆にすると、汎用が先に多くを拾ってしまい、専用の速さを活かせません。優先順位は、範囲の狭さと速さのバランスで決めます。
Optimized computation kernels in core ONNX Runtime provide performance improvements and assigned subgraphs benefit from further acceleration from each Execution Provider.原文ONNX Runtime 公式ドキュメント「Get Started」 この内容の有効期限2027-02-18
機種をまたいで動く形式です。展開先が増えるほど、個別に作り直すより作業量が軽くなります。
ONNX Runtimeは、機種をまたいで動く前提です。公式はONNX Runtimeは、機材ごとの部品を組み込む柔軟な入口を持つ、機種をまたぐ機械学習モデルの高速化の仕組みであると述べています。
機種をまたげる価値は、展開先の数で変わります。実際に計算して比べました。
更新を 8回行う。展開先の数を変えて、総作業時間を比べる
展開先の数 共通形式(初回+更新) 個別に移植(初回+更新) 比
1箇所 30時間 56時間 1.9倍
3箇所 78時間 167時間 2.1倍
6箇所 150時間 334時間 2.2倍
12箇所 294時間 667時間 2.3倍
1箇所でも共通形式のほうが30時間対56時間、1.9倍軽く済みます。初回の書き出しが1回で済むためです。
12箇所になると294時間対667時間で、2.3倍まで差が開きます。
1箇所しかない場合の差は1.9倍です。展開先を増やす予定がなければ、共通形式にする効果は限られます。
差が大きく開くのは、更新を繰り返しながら展開先を増やしていく場合です。最初にどちらを選ぶかで、後からの負担が変わります。
3つの計測はいずれも手元で書いた模型で、実際のONNX Runtimeを動かしたものではありません。1演算4μs・210μs・受け渡し35μsといった値、実行役ごとの速さと対応範囲、共通形式と個別移植の工数はすべて置いたものです。対応していない演算の並び方も生成したもので、実際のモデルでは偏り方が異なります。ここで見せているのは、対応割合が10%欠けるだけで時間が大きく跳ねるという点と、優先順位の並べ方だけで結果が変わるという点の2つです。
ONNX Runtime is a cross-platform machine-learning model accelerator, with a flexible interface to integrate hardware-specific libraries.原文ONNX Runtime 公式ドキュメント「Get Started」 この内容の有効期限2027-02-18
同じ課題を持つ会社にとって、動いている設定は「作る時間」を買えるということです。ServiceDockは自作のワークフローやテンプレートを出品できるマーケットプレイスです。手数料や出品の流れは出品者向けページにまとまっています。
出品の仕組みを見る