TensorRT を呼び出す C# に基づいて Yolov5 モデルをデプロイする
NVIDIA TensorRT™ は、ディープ ラーニング推論アプリケーションに低遅延と高スループットを提供する、高性能ディープ ラーニング推論用の SDK です。詳細なインストール方法については、次のブログを参照してください。NVIDIA TensorRT インストール (Windows C++)
前の記事では、TensorRT を使用して Yolov5 モデルを C++ にデプロイする方法を紹介しましたが、実際のアプリケーションでは、多くの場合、モデルを にデプロイする必要があります。 C#. 現在、TensorRT は C# で Yolov5 モデルを直接インストールすることはできません。関数インターフェイスを呼び出してモデル デプロイメントを実装します。ここでは、ダイナミック リンク ライブラリ関数を使用して TensorRTSharp を構築し、C# デプロイメント モデルを実装します。
2. Nvinfer クラスを構築する
2.1 新しい C# クラス ライブラリを作成する
ソリューションを右クリックし、[追加]、[新しいプロジェクト] の順に選択し、[C# クラス ライブラリの追加] を選択し、プロジェクトに名前を付けcsharp_tensorrt_class
、コンピューターのフレームワークに従ってプロジェクト フレームワークを選択します。ここでは .NET 5.0 を使用します。作成が完了したら、プロジェクトを右クリックし、[追加] -> [新しい項目] を選択し、クラス ファイルを選択し、クラス ファイルを 2 つNvinfer.cs
追加します。NativeMethods.cs
2.2 DLL ファイルにメソッドをインポートする
NativeMethods.cs ファイルの下で、[DllImport()]
メソッドを通じて dll ファイル内のすべてのメソッドを C# に読み込みます。モデルの変換方法は次のようになります。
[DllImport(tensorrt_dll_path, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
public extern static void onnx_to_engine(string onnx_file_path, string engine_file_path, int type);
このうち、openvino_dll_path は dll ファイルのパス、CharSet = CharSet.Unicode は中国語のエンコード形式文字列がサポートされていることを意味し、CallingConvention = CallingConvention.Cdecl は、エントリ ポイントの呼び出し規約が呼び出し元のスタックをクリーンアップすることを示します。
上記のリストは推論モデルを初期化するためのもので、dlii ファイルのインターフェースが一致する場合はメソッド名も一致するため、メソッド名は dll ファイルと一致している必要があります。2つ目はメソッドのパラメータの型に対応するもので、上記のメソッドでは関数の戻り値はC++ではvoid*、C#では対応するIntPtr型になります、入力パラメータのうちwchar_t*文字ポインタですC++、C# では string 文字列に相当します。メソッド名とパラメータの型を 1 対 1 に対応させることで、C# でメソッド呼び出しを実現できます。他のメソッドは次のように C# で書き直されます。
// 读取本地engine模型,并初始化NvinferStruct
public extern static IntPtr nvinfer_init(string engine_filename, int num_ionode);
// 创建GPU显存输入/输出缓冲区
public extern static IntPtr creat_gpu_buffer(IntPtr nvinfer_ptr, string node_name, ulong data_length);
// 加载图片输入数据到缓冲区
public extern static IntPtr load_image_data(IntPtr nvinfer_ptr, string node_name, ref byte image_data, ulong image_size, int BN_means);
// 模型推理
public extern static IntPtr infer(IntPtr nvinfer_ptr);
// 读取推理数据
public extern static void read_infer_result(IntPtr nvinfer_ptr, string node_name_wchar, ref float result, ulong data_length);
// 删除内存地址
public extern static void nvinfer_delete(IntPtr nvinfer_ptr);
2.3 Nvinfer クラスの作成
dll を通じて導入した TensorRT メソッドをより便利に呼び出し、使用時の関数メソッド インターフェイスを減らすために、独自の推論クラスを C# で再編成し、 という名前を付けました。その主要なメンバー変数とメソッドは Nvinfer クラス図に示されていますClass Nvinfer
。 。
public class Nvinfer{}
Nvinfer クラスでは、インターフェイス関数から返される推論コア ポインターを受け取るために、Nvinfer クラスのメンバー変数としてアドレス変数を作成するだけでよく、現在のクラスでこのメンバー変数にアクセスする必要があるだけなので、次のように設定します。プライベート変数:
private IntPtr ptr = new IntPtr();
まず、モデル変換メソッドをカプセル化しますonnx_to_engine()
。これは主に onnx モデルをエンジン形式に変換するために使用されます。エンジンはローカル構成に基づいて変換された推論モデル ファイルであるため、モデル ファイルは汎用ではなく、独自に変換する必要があります。 。このメソッドでは、ローカルの onnx モデル ファイル、変換されたエンジンのローカル ストレージ パス、および変換されたモデルの精度タイプを入力し、書き換えられたメソッドを呼び出すだけですNativeMethods.onnx_to_engine()
。
public void onnx_to_engine(string onnx_file_path, string engine_file_path, AccuracyFlag type){
NativeMethods.onnx_to_engine(onnx_file_path, engine_file_path, (int)type);
}
次に、推論モデルの初期化メソッドを構築しますinit()
。エンジン モデル ファイルのパス アドレスと入力ノードと出力ノードの数を入力するだけで、NativeMethods.nvinfer_init()
エンジン モデルのローカル読み取りを実現し、初期化できるメソッドを呼び出します。推論エンジン構造のメンバー変数内の関連するダウンロード。
public void init(string engine_filename, int num_ionode){
ptr = NativeMethods.nvinfer_init(engine_filename, num_ionode);
}
creat_gpu_buffer()
これは主に、GPU メモリ内の入出力バッファの作成を実装します。ここで、入出力ノード名と入出力ノードのデータ サイズを指定する必要があります。
public void creat_gpu_buffer(string node_name, ulong data_length){
ptr = NativeMethods.creat_gpu_buffer(ptr, node_name, data_length);
}
load_image_data()
このメソッドは主に推論付きデータを推論モデルにロードします. このメソッドの入力画像データは行列に変換された画像データです, これは C++ と C# の間で画像データを転送するのに便利です. このメソッドには画像が含まれていますデータの前処理やその他の手順を実行するため、ここではデータの前処理を行う必要はありません。
public void load_image_data(string node_name, byte[] image_data, ulong image_size, BNFlag BN_means){
ptr = NativeMethods.load_image_data(ptr, node_name, ref image_data[0], image_size, (int)BN_means);
}
infer()
主な手順は、モデル推論メソッドを呼び出して、構成されたデータに対してモデル推論を実行することです。
public void infer(){
ptr = NativeMethods.infer(ptr);
}
read_infer_result()
主にモデル推論後の推論結果データの読み込みを実現します。現在、結果のデータ型は浮動小数点データの読み込みのみサポートしています。将来的に他のデータ読み込み要件があれば、需要に応じて変更されます。 。
public float[] read_infer_result(string node_name_wchar,ulong data_length){
float[] result = new float[data_length];
NativeMethods.read_infer_result(ptr, node_name_wchar, ref result[0], data_length);
return result;
}
最後のステップは主にメモリ データの削除です。メモリを配置しすぎるとメモリ リークが発生します。
public void delete(){
NativeMethods.nvinfer_delete(ptr);
}
2.4 Nvinfer クラス ライブラリをコンパイルする
プロジェクトを右クリックし、「生成/再生成」をクリックすると、図のような画面が表示され、コンパイルが成功したことがわかります。