Python 環境で ONNX モデルを fp16 半精度浮動小数点メソッドに変換する

バックグラウンド

Jetpack4.6.2 の TensorRT8.2 は 16G メモリでの NX サポートに問題があり、実行できません (8G メモリは問題ありません)。実行できる TensorRT7 は私をサポートしていません。エッジモデルで使用されているeinsum操作なので、fp16に変更して実行して確認しようと思いました

参考

https://blog.csdn.net/znsoft/article/details/114538684

プロセス

  1. リファレンスコードは非常にシンプルですが、Python環境のインストールが少々面倒なので、仮想環境を作成してインストールすることを推奨します。誰かが直接インストールしているようです。
  2. python3.7の新しい仮想環境を作成します。私は python3.7 に基づいて新しい conda 環境を作成しました。20220513 の時点では、この winmltools はpython3.8 にインストールできず、ビルド ホイールがエラーを報告してスタックすることに注意してください。で、ようやく 3.7 Python をインストールしました。ちなみに、この壊れたものにどうしてそんなに多くのバージョンの scipy か何かをインストールする必要があるのでしょうか。とんでもないことです。
  3. コマンドラインによる直接インストール:
pip install winmltools
  1. インストール後、次のコードに従ってモデルを変更できる可能性があります。
from winmltools.utils import convert_float_to_float16
from winmltools.utils import load_model, save_model
onnx_model = load_model('model.onnx')
new_onnx_model = convert_float_to_float16(onnx_model)
save_model(new_onnx_model, 'model_fp16.onnx')

エラーを報告する

ここでこのモデルで小さな問題が発生し、エラーが報告されました。

(op_type:AveragePool, name:AveragePool_141): Inferred shape and existing shape differ in dimension 2: (8) vs (7)
Traceback (most recent call last):
  File "G:/jupyter/fp16_convert/fp16_convert.py", line 4, in <module>
    new_onnx_model = convert_float_to_float16(onnx_model)
  File "D:\ProgramData\Anaconda\envs\fp16_convert\lib\site-packages\onnxconverter_common\float16.py", line 139, in convert_float_to_float16
    model = func_infer_shape(model)
  File "D:\ProgramData\Anaconda\envs\fp16_convert\lib\site-packages\onnx\shape_inference.py", line 36, in infer_shapes
    inferred_model_str = C.infer_shapes(model_str)
RuntimeError: Inferred shape and existing shape differ in dimension 2: (8) vs (7)

Process finished with exit code 1

私が確認したので、他のモデルでは onnx への転送時に小さなバグが発生している可能性があります。推論部分はスキップしてください。エラーの内容に従ってshape_inference.pyにジャンプし、次の変更を加えます。


def infer_shapes(model):  # type: (ModelProto) -> ModelProto
    if not isinstance(model, ModelProto):
        raise ValueError('Shape inference only accepts ModelProto, '
                         'incorrect type: {}'.format(type(model)))
    model_str = model.SerializeToString()
    return onnx.load_from_string(model_str)
    inferred_model_str = C.infer_shapes(model_str)
    return onnx.load_from_string(inferred_model_str)

コードを再実行して正常に生成し、NX 開発ボードに配置して実行します。これは float よりも約 1.5 倍高速です。

おすすめ

転載: blog.csdn.net/weixin_42492254/article/details/124757094