C
C向けORT入門
Section titled “C向けORT入門”| アーティファクト | 説明 | サポートされているプラットフォーム |
|---|---|---|
| Microsoft.ML.OnnxRuntime | CPU (リリース) | Windows, Linux, Mac, X64, X86 (Windowsのみ), ARM64 (Windowsのみ)…詳細: 互換性 |
| Microsoft.ML.OnnxRuntime.Gpu | GPU - CUDA (リリース) | Windows, Linux, Mac, X64…詳細: 互換性 |
| Microsoft.ML.OnnxRuntime.DirectML | GPU - DirectML (リリース) | Windows 10 1709+ |
| onnxruntime | CPU, GPU (開発版), CPU (オンデバイストレーニング) | リリース版と同じ |
| Microsoft.ML.OnnxRuntime.Training | CPU オンデバイストレーニング (リリース) | Windows, Linux, Mac, X64, X86 (Windowsのみ), ARM64 (Windowsのみ)…詳細: 互換性 |
.zipおよび.tgzファイルは、各Githubリリースのアセットとしても含まれています。
APIリファレンス
Section titled “APIリファレンス”onnxruntime_c_api.hを参照してください。
- onnxruntime_c_api.hをインクルードします。
OrtCreateEnvを呼び出します。- セッションを作成します:
OrtCreateSession(env, model_uri, nullptr,...)- オプションで、さらに実行プロバイダーを追加します (例: CUDAには
OrtSessionOptionsAppendExecutionProvider_CUDAを使用)。
- オプションで、さらに実行プロバイダーを追加します (例: CUDAには
- テンソルを作成します。
OrtCreateMemoryInfoOrtCreateTensorWithDataAsOrtValue
OrtRunを呼び出します。
- ディスク上のモデルファイルと
SessionOptionsのセットからInferenceSessionを作成します。 - カスタマイズされたロガーを登録します。
- カスタマイズされたアロケータを登録します。
- 事前定義されたプロバイダーを登録し、優先順位を設定します。ONNXRuntimeには、CUDA、DNNLなどの事前定義された実行プロバイダーのセットがあります。ユーザーはプロバイダーを
InferenceSessionに登録できます。登録の順序は、優先順位も示します。 - 入力を使用してモデルを実行します。これらの入力はGPUメモリではなく、CPUメモリにある必要があります。モデルに複数の出力がある場合、ユーザーはどの出力が必要かを指定できます。
- プロトコルバッファ形式でエンコードされたメモリ内のONNXテンソルを、モデル入力として使用できるポインターに変換します。
- 各セッションのスレッドプールサイズを設定します。
- 各セッションのグラフ最適化レベルを設定します。
- カスタムOPを動的にロードします。手順
- バイト配列からモデルをロードする機能。
onnxruntime_c_api.hのOrtCreateSessionFromArrayを参照してください。 - グローバル/共有スレッドプール: デフォルトでは、各セッションは独自のスレッドプールのセットを作成します。同じプロセスで複数のセッション(異なるモデルを推論するため)を作成する必要がある状況では、各セッションによって作成された複数のスレッドプールができてしまいます。この非効率性に対処するために、グローバル/共有スレッドプールと呼ばれる新機能を導入します。基本的な考え方は、複数のセッション間でグローバルスレッドプールのセットを共有することです。この機能の一般的な使用方法は次のとおりです。
ThreadingOptionsを入力します。ORTがデフォルトを選択するように0の値を使用します。CreateEnvWithGlobalThreadPools()を使用してenvを作成します。- セッションを作成し、セッションオプションオブジェクトで
DisablePerSessionThreads()を呼び出します。 - 通常どおり
Run()を呼び出します。
- セッション間でアロケータを共有:
- 説明: この機能により、同じプロセス内の複数のセッションが同じアロケータを使用できます。
- シナリオ: 同じプロセスに複数のセッションがあり、メモリ使用量が高い場合。この理由の1つは次のとおりです。各セッションは、デフォルトでアリーナベースである独自のCPUアロケータを作成します。ORTは、Doug Leaの合体アルゴリズムによるベストフィットに基づいたアリーナアロケータの簡略版を実装しています。各アロケータは独自のセッションに存在します。初期化時に大きなメモリ領域を割り当て、その後、割り当て/割り当て解除の要求に応じて、この初期領域をチャンク、合体、拡張します。時間が経つにつれて、アリーナはセッションごとに未使用のメモリチャンクで終わります。さらに、アリーナによって割り当てられたメモリはシステムに返されません。一度割り当てられると、常に割り当てられたままになります。これらの要因はすべて、複数のセッション(それぞれが独自のアリーナを持つ)を使用する場合に加算され、プロセスの全体的なメモリ消費量が増加します。したがって、セッション間でアリーナアロケータを共有することが重要になります。
- 使用方法:
CreateAndRegisterAllocatorAPIを使用して、共有アロケータを作成し、envに登録します。このアロケータは、セッションがsession_state.use_env_allocatorsを「0」に設定してこれをオーバーライドしない限り、同じenvインスタンスを使用するすべてのセッションによって再利用されます。- envに登録されたアロケータを使用したい各セッションについて、
session.use_env_allocatorsを「1」に設定します。 - 例については、https://github.com/microsoft/onnxruntime/blob/main/onnxruntime/test/shared_lib/test_inference.ccのテスト```TestSharedAllocatorUsingCreateAndRegisterAllocator```を参照してください。
- OrtArenaCfgの設定 (ORTリリース1.8以降ではAPI
CreateArenaCfgV2を使用してOrtArenaCfgインスタンスを作成し、それ以前のリリースでは非推奨となったCreateArenaCfgを使用してインスタンスを作成):CreateArenaCfgV2は、以下に説明するキーのリストと、対応する値のセット(各キーに1つ)を取ります。これらの設定のデフォルト値は、BFCArenaクラスにあります。CreateArenaCfgV2の使用例については、https://github.com/microsoft/onnxruntime/blob/main/onnxruntime/test/shared_lib/test_inference.ccのテスト```ConfigureCudaArenaAndDemonstrateMemoryArenaShrinkage```を参照してください。max_mem: これはアリーナが割り当てる最大メモリ量です。チャンクが既存のどの領域でもサービスを提供できない場合、アリーナは利用可能なメモリ(max_mem - これまでに割り当てられた量)に応じて、さらに1つの領域を割り当てることによって自身を拡張します。利用可能なメモリが要求された拡張よりも少ない場合、エラーが返されます。arena_extend_strategy: これは現在、kSameAsRequestedまたはkNextPowerOfTwoの2つの値しか取れません。名前が示すように、kNextPowerOfTwo (デフォルト)はアリーナを2のべき乗で拡張し、kSameAsRequestedは毎回割り当て要求と同じサイズで拡張します。kSameAsRequestedは、予想されるメモリ使用量を事前に知っている、より高度な設定に適しています。initial_chunk_size_bytes: この設定は、アリーナ拡張戦略がkNextPowerOfTwoの場合にのみ関連します。これは、アリーナが最初の割り当てで割り当てる(可能性のある)領域のサイズです(最初のメモリ要求がこれより大きい場合、割り当てサイズは指定された値よりも大きくなります)。チャンクは、この領域からの割り当て要求に渡されます。ログがアリーナが予想以上に拡張されていることを示している場合は、これに十分な大きさの初期サイズを選択することをお勧めします。initial_growth_chunk_size_bytes: このセクションを読む前に、「メモリ アリーナの縮小」のセクションをお読みください。この設定は、アリーナ拡張戦略がkNextPowerOfTwoの場合にのみ関連します。現在、この値はアリーナ縮小後の最初の割り当ての(可能性のある)サイズです(アリーナ縮小後のこの値より大きいメモリ要求は、より高い割り当てサイズになります)。アリーナによる(可能性のある)最初の割り当てはinitial_chunk_size_bytesによって定義され、可能性のある後続の割り当てはinitial_chunk_size_bytes * 2、initial_chunk_size_bytes * 4などです。アリーナがこれらのメモリ領域のいずれかを縮小(つまり、割り当て解除)する場合、縮小後の最初の割り当てのサイズを「リセット」したいと考えています。これが現在の定義です。将来的には、この設定はアリーナの他の「成長中心」のアクション(つまり、最初の割り当て(初期チャンク)後のアリーナによる2番目の割り当て(アリーナの成長))を制御するために使用される可能性があります。max_dead_bytes_per_chunk: これは、割り当て要求を処理するためにチャンクを分割するかどうかを制御します。現在、チャンクサイズと要求されたサイズの差がこの値より小さい場合、チャンクは分割されません。これにより、プロセス全体でチャンクの一部が未使用のままになる(したがってデッドバイトと呼ばれる)ことでメモリを浪費し、メモリ使用量が増加する可能性があります(このチャンクがアリーナに返されるまで)。
- メモリ アリーナの縮小:
- 説明: デフォルトでは、メモリアリーナは縮小しません(未使用のメモリをシステムに返しません)。この機能により、ユーザーは特定の頻度でアリーナを「縮小」できます。現在サポートされている唯一の頻度は、すべてのRun()の終わりです(つまり、この機能が使用されている場合、すべてのRun()の終わりに未使用のメモリを解放する可能性があるためにアリーナメモリがスキャンされます)。これはRunOptionを介して実現されます。
- シナリオ: 大量のメモリを割り当てる必要がある要求を時々処理する動的形状モデルがあるとします。デフォルトでは、アリーナはメモリを解放しないため、この要求を処理する一部としてのアリーナのこの「成長」は永久に保持されます。これは、他のほとんどの要求がそれほど多くのメモリを必要としないため、最適ではありません(つまり、1つか2つの外れ値を処理するためだけにあまりにも多くのメモリが割り当てられてしまいます)。これがORTの使用シナリオを最もよく表している場合は、この縮小機能を使用するオプションがあります。この機能は、関連するメモリアロケータがそもそもアリーナベースのアロケータである場合にのみ適用されます。
- 使用方法: 例については、https://github.com/microsoft/onnxruntime/blob/main/onnxruntime/test/shared_lib/test_inference.ccのテスト```ConfigureCudaArenaAndDemonstrateMemoryArenaShrinkage```を参照してください。この機能を最適に使用するには、縮小されるメモリアリーナをユースケースに合わせて適切に構成する必要があります。上記の```OrtArenaCfg```インスタンスを使用してアリーナアロケータを構成する方法を参照してください。この機能は、以下で説明するように、利用可能な2つのアリーナ拡張戦略(kSameAsRequestedとkNextPowerOfTwo)に基づいてわずかに味付けされています。
kNextPowerOfTwo: これが選択された構成である場合、初期割り当てを除くすべてのメモリアロケーションが縮小時に割り当て解除の対象と見なされます。考え方としては、ユーザーがほとんどのモデル要求をより多くのメモリを割り当てることなく処理するために十分な高さのinitial_chunk_size_bytesを設定する(つまり、この初期メモリは平均的な要求を処理するのに十分である)ということです。外れ値要求を処理する一部として割り当てられる後続の割り当てのみが、割り当て解除の候補となります。kSameAsRequestedこれが選択された構成である場合、すべてのメモリアロケーションが縮小時機に割り当て解除の対象と見なされます。これは、現在、initial_chunk_size_bytesがこの戦略に関連していないためです。
- 非アリーナメモリから初期化子のメモリを割り当てる (上級ユーザー向け):
- 説明: 初期化子の内容を格納するデバイスに関連するアロケータがアリーナベースのアロケータであり、これらの初期化子のメモリを割り当てることから生じる(可能性のある)過剰なアリーナの成長を防ぎたい場合、これがそのような機能を提供する機能です。
- シナリオ: Run()自体では多くのメモリを割り当てる必要がないかなり単純なモデルがありますが、モデルには比較的大量の初期化子があり、アリーナを使用してこれらのメモリが割り当てられると、全体のアリーナ割り当てメモリ内の未使用メモリがRun()中にモデルに実際に必要なものをはるかに超える可能性があります。このような状況で、モデルをメモリに制約のある環境にデプロイする場合、アリーナ内の初期化子メモリ割り当ての一部として生じるアリーナの過剰な成長を防ぐために、このような機能を使用することは理にかなっています。この機能を使用すると、アリーナはモデルの演算子のみが必要とするメモリを割り当てるためにのみ使用されることを意味します。
初期化子とRun()中に予想されるメモリを考慮してアリーナに十分な初期チャンクサイズ(
initial_chunk_size_bytes)を設定することで、問題のあるシナリオを回避できるように思えます。これに関する問題は、一部のEPが内部でスレッドごとのアロケータを使用し、構成で設定された高い初期チャンクサイズがこれらのそれぞれに適用され、最終的に1つのスレッドごとのアロケータのみが初期化子のメモリを割り当てるため、メモリの浪費につながることです。 - 使用方法: 例については、https://github.com/microsoft/onnxruntime/blob/main/onnxruntime/test/shared_lib/test_inference.ccのテスト```AllocateInitializersFromNonArenaMemory```を参照してください。
- セッション間で初期化子とそのORT前処理済みバージョンを共有:
- 説明: この機能により、ユーザーは複数のセッション間で同じ初期化子インスタンス(およびそのORT「前処理済み」バージョン)を共有できます。
- シナリオ: モデルの最後の数層を除いて同じ初期化子セットを使用するモデルがいくつかあり、これらのモデルを同じプロセスにロードするとします。すべてのモデル(セッション)が同じ初期化子の別のインスタンスを作成すると、この場合は同じ初期化子であるため、過剰で無駄なメモリ使用量につながります。初期化子を割り当てる(場合によっては共有メモリに保存することも可能)柔軟性を持ちながら、メモリ使用量を最適化したいと考えています。
- 使用方法:
CreateSessionを呼び出す前に、AddInitializerAPIを使用して、事前に割り当てられた初期化子をセッションオプションに追加します。同じセッションオプションのインスタンスを使用して複数のセッションを作成し、セッション間で初期化子を共有できるようにします。C APIの使用例 (TestSharingOfInitializerAndItsPrepackedVersion)およびC# APIの使用例 (TestSharingOfInitializerAndItsPrepackedVersion)を参照してください。 - 一部のORT演算子の実装では、一部のプラットフォームで最適な演算子推論を促進するために、モデルのロード時に初期化子が前処理されます(「プリパッキング」と呼ばれるプロセス)。デフォルトでは、これらの前処理されたバージョンの初期化子はセッションごとに維持されます(つまり、セッション間で共有されません)。これらをセッション間で共有できるようにするには、コンテナを作成し(
CreatePrepackedWeightsContainerを使用)、セッション作成時にこれを渡して、セッション間で共有初期化子のプリパックバージョンの共有が行われ、これらがメモリ内で複製されないようにします。上記のCおよびC#で参照されている同じテストは、この機能の使用例も示しています。 注: プリパッキングを実装したいカーネル開発者は、カーネルを使用して可能な限りプリパックできるすべての重みのプリパッキングをトリガーするテストを記述し、セッション間でこれらのプリパックされた重みの共有をテストする必要があります。カーネルテスト (SharedPrepackedWeights)を参照してください。
Windows 10
Section titled “Windows 10”インストーラーは、onnxruntime.dllをアプリケーションと同じフォルダに配置する必要があります。アプリケーションは、ロード時ダイナミックリンクまたは実行時ダイナミックリンクのいずれかを使用してdllにバインドできます。
ダイナミックリンクライブラリの検索順序
Section titled “ダイナミックリンクライブラリの検索順序”これは、Windowsがサポートするdllを見つける方法に関する重要な記事です: ダイナミックリンクライブラリの検索順序。
アプリがonnxruntimeを直接消費するのではなく、onnxruntimeを消費しているDLLを呼び出している場合があります。onnxruntimeを消費するこれらのDLLをビルドする人は、フォルダ構造に注意する必要があります。システム%path%変数を変更してフォルダを追加しないでください。これは、onnxruntmeも使用しているマシンの他のソフトウェアと競合する可能性があります。代わりに、DLLとonnxruntime DLLを同じフォルダに配置し、実行時ダイナミックリンクを使用してそのコピーに明示的にバインドします。このサンプルがGetModulePath()で行っているようなコードを使用して、dllがロードされたフォルダを見つけることができます。
公式のWindowsビルドでテレメトリ収集をオン/オフにするには、C APIでEnable/DisableTelemetryEvents()を使用してください。テレメトリ収集とMicrosoftのプライバシーポリシーの詳細については、プライバシーページを参照してください。
Candy Style Transferを参照してください。