This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] AM62A7:编译自定义模型时出现问题

Guru**** 2473260 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1459943/am62a7-problem-compiling-custom-model

器件型号:AM62A7

工具与软件:

您好!

我一直在尝试将定制模型的推理转移到 AM62A 板的 C7x/MMA 内核、但没有很多成功。 与论坛上和 TIDL Tools / EdgeAI Academy 材料上讨论的绝大多数问题不同、我需要执行的推理类型不涉及图像处理。 相反,该模型对结构为熊猫数据帧的元数据进行分类。 该模型使用 sklearn 库进行训练、并使用 skl2onnx 和 TFLiteConverter 通过 keras 导出到 ONNX 和 TFLite。 两种转换后的模型都可以在 ARM 处理器上顺利运行、但在 C7x/MMA 加速器上不会运行。

尝试编译 TFLite 模型时、仅在 custom-artifies 文件夹中生成 tempDir。 对于 ONNX 模型、我尝试了两种编译方法:调整示例文件夹中提供的 Jupyter 笔记本、以及调整 examples/osrt_python/ort 文件夹中提供的 onnxrt_ep.py 脚本。 后者似乎会产生更好的结果、因为它会在 tempDir 中生成更多的文件并提供更广泛的调试信息。 ‘、脚本在"Quantization & Calibration for subgraph_0"期间挂起、从而导致在 custom-artifacts 文件夹中生成以下文件:

  • allowedNode.txt
  • onnxrtMetaData.txt
  • /tempDir
    • graphvizInfo.txt
    • runtimes_visualization.svg
    • subgraph_0_calib_raw_data.bin
    • subgraph_0_tidl_io_1.bin
    • subgraph_0_tidl_net.bin
    • subgraph_0_tidl_net.bin.layer_info.txt
    • subgraph_0_tidl_net.bin.svg
    • subgraph_0_tidl_net.bin_netLog.txt

它在挂起前提供以下错误/警告时刻:

============= [Quantization & Calibration for subgraph_0 Started] =============

2025-01-08 14:46:34.193707173 [E:onnxruntime:, sequential_executor.cc:494 ExecuteKernel] Non-zero status code returned while running Gemm node. Name:'gemm_token_0' Status Message: /root/onnxruntime/onnxruntime/core/providers/cpu/math/gemm_helper.h:14 onnxruntime::GemmHelper::GemmHelper(const onnxruntime::TensorShape&, bool, const onnxruntime::TensorShape&, bool, const onnxruntime::TensorShape&) left.NumDimensions() == 2 || left.NumDimensions() == 1 was false. 

Process Process-1:
Traceback (most recent call last):
  File "/usr/lib/python3.10/multiprocessing/process.py", line 314, in _bootstrap
    self.run()
  File "/usr/lib/python3.10/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "/home/root/examples/osrt_python/ort/onnxrt_ep.py", line 415, in run_model
    classified_data = run_prediction(sess, scaled_data)
  File "/home/root/examples/osrt_python/ort/onnxrt_ep.py", line 142, in run_prediction
    predictions = session.run([output_name], {input_name: input_data})[0]
  File "/usr/local/lib/python3.10/dist-packages/onnxruntime/capi/onnxruntime_inference_collection.py", line 200, in run
    return self._sess.run(output_names, input_feed, run_options)
onnxruntime.capi.onnxruntime_pybind11_state.RuntimeException: [ONNXRuntimeError] : 6 : RUNTIME_EXCEPTION : Non-zero status code returned while running Gemm node. Name:'gemm_token_0' Status Message: /root/onnxruntime/onnxruntime/core/providers/cpu/math/gemm_helper.h:14 onnxruntime::GemmHelper::GemmHelper(const onnxruntime::TensorShape&, bool, const onnxruntime::TensorShape&, bool, const onnxruntime::TensorShape&) left.NumDimensions() == 2 || left.NumDimensions() == 1 was false. 

按照 TIDL git 中提供的建议、在模型的 deny_list 中包含可能有问题的节点、我修改了 model_configs.py 文件、如下所示:

    "myModel": create_model_config(
        source=AttrDict(
            infer_shape=True,
        ),
        preprocess=AttrDict(
        ),
        session=AttrDict(
            session_name="onnxrt",
            model_path=os.path.join(models_base_path, "myModel.onnx"),
        ),
        task_type="other",
        extra_info=AttrDict(
        ),
        optional_options={
            'deny_list' : 'Gemm',
        }
    ),

但是、虽然该节点已成功添加到不受支持的节点列表中、但脚本仍然挂起、并提供完全相同的输出。

------------------------------------------------------------------------------------------------------------------------------------------------------
|         Node          |       Node Name       |                                               Reason                                               |
------------------------------------------------------------------------------------------------------------------------------------------------------
| Gemm                  | gemm                  | Node gemm added to unsupported nodes as specified in deny list                                     |

我用于执行上述编译的 Docker 文件在 SDK 版本10_00_08_00下配置、这与我在 AM62A 上的相同、ONNXRuntime 版本为1.14.0。 为了检查 Docker 和电路板的配置设置、我已成功执行 ARM 和 C7x/MMA 处理器的 examples/jupyter_notebooks 文件夹中的一些示例。

但是、考虑到 onnxrt_ep.py 脚本侧重于图像处理示例、我必须注释掉、修改并包含其他推理和数据预处理方法、才能编译我的自定义模型。 可以想象、评估我所做修改对整个编译过程的影响并不简单。 值得注意的是、编译过程成功识别了一组应卸载到加速器的节点、以及一组可能已卸载但出于编译过程中所述原因的节点。 我随附了我修改后的 onnxrt_ep.py 脚本版本、并在我已添加到文件的代码顶部添加了####:  

e2e.ti.com/.../e2e_5F00_onnxrt_5F00_ep.zip

此致、

Giann。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、Giann、

    我可以看到你们已经在这里做了功课,并为此付出了大量的努力。 我很高兴看到这一点、我们将寻求解决您面临的挑战。  

    从日志和注释中可以看到、GEMM/矩阵乘法层未随 TIDL 运行。 如果您不 拒绝此图层类型、我会很想看到警告/日志、以及原始模型文件中该图层的配置是什么样子。 如果您愿意分享、从 Netron 获得的该层的截图将是完美的。  

    因此、当您的层未在加速器上随 TIDL 运行时、它需要该 GEMM 层的 ONNX Runtime 实现。 ONNX 正在向 GEMM 层抛出有关输入大小的警告。  

    请尝试在调用 Linux 环境中将 TIDL_RT_ONNX_VARDIM 环境变量设置为"1" .

    export TIDL_RT_ONNX_VARDIM=1

    这会告诉 TIDL 在将数据传回 ONNX 时压缩/删除不需要的尺寸。 默认情况下,TIDL 倾向于使用6-D 表示法——这个 env 变量就是用来解决这个问题的。  

    • 需要注意的是、10.1 SDK 版本不需要此选项(为此需标记10_01_00_02)。 AM62A 将在接下来的几周内发布此 SDK。  

    该进程很可能挂起、因为 onnxrt_ep.py 希望为您正在编译的每个模型创建一个线程。 如果您的模型在编译期间遇到故障、它将无法在 Python 中正确退出该线程、您可以使用 KeyboardInterrupt 来安全退出

    BR、
    Reese

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、Giann、

    Reese 本周即将结束、下周才能回复。

    此致、

    建中

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、Giann、

    感谢您在我外出时的耐心等待。 我感谢您在答复中收集信息的努力。

    您的模型工件文件夹实际上看起来不完整。 如您所述、它缺少子图二进制文件、这些二进制文件会在完成时复制到顶部工件文件夹中(自动、不会遗漏一个步骤)。  tempDir 中的文件尚未完全完成、我们不能正确卸载、它们是中间文件。  

    这些二进制文件是 onnxruntime 用来卸载指令的吗? 您能告诉我生成这些二进制文件的编译脚本部分吗? [报价]

    subgraph_N_tidl_net.bin 和..._io_1.bin 是 TIDL 读取的用于设置网络并加速运行的二进制文件。 在整个编译过程中、这些编译的中间版本用作编译过程中不同点的基础。 由于校准/量化尚未完成、你在 tempDir 中具有的值有可能适用于32位浮点模式。

    在 onnxrt_ep.py 中、 将网络设置为在创建 InferenceSession 时运行编译、以 TIDLCompilationProvider 为目标:

    第二个阶段(来自用户级)发生在将映像传递到运行时之后(至少与 ADVANCED_OPTIONS:CALIBRATION_FRAMES 参数一样多)。 到达足够多后、它会以浮点模式运行这些输入以捕获一些统计信息、然后尝试校准几次、以便找到良好的浮点->定点转换函数。

    在第三个子图的优化阶段(校准前)、它看起来像您的模型、其中仅包含 softmax 层、并且不包含拒绝列表挂起。  应该拒绝列出此图层类型、看看这是否是问题所在。 您的 SoftMax 图层是否符合"支持操作"页面中列出的条件?

    我想知道 GEMM 配置有什么错误、导致该层被拒绝。 您是否对该层有与输出尺寸相匹配的偏置?

    BR、
    Reese

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、Giann、

    关于它的价值、作为另一项调试工作的一部分、我已经使用 PyTorch 而不是 Sklearn 重新训练了模型、以检查是否有任何差异、确实有差异。 使用 PyTorch 训练的模型各层似乎从一开始就受编译器支持:

    我想说的是、这绝对值得知道。 将模型从训练框架导出为推理/交换格式(例如、Pytorch -> ONNX)可能会对生成的模型产生影响。 导出可以添加并非完全有意的图层/配置、尤其是当图层/操作或参数存在于一个框架中但不存在于另一个框架中时。

    有趣的是,你有一个问题与 SKLearn 的输出,但不是 Pytorch. 然而,更奇怪的是,这个 Pytore-exported 模型给问题仍然存在,在该汇编挂起。

    我想我接下来的调试工作将包括修改模型、以确保从一开始就遵守支持操作页面中列出的标准。

    是的、这将是一个伟大的步骤。 您可能会发现模型导出是导致这些"不受支持"配置的原因。 tidl-onnx-model-optimizer 是通过编程更新任何此类配置的好方法、或者、onnx-modifier 是一个很好的 GUI 工具、但复制起来会更加繁琐。

    [报价 userid="633019" url="~/support/processors-group/processors/f/processors-forum/1459943/am62a7-problem-compiling-custom-model/5627044 #5627044"]

    即使校准+优化从未完成、编译过程也不会显示警告:

    [报价]

    让我们进一步考虑这一点、因为即使您的模型显示100%的层被委派给 TIDL 进行加速、您也无法获得可用的结果。 当您再次运行此日志时、请添加以下内容并共享日志:

    • 在通过运行时 API 初始化模型时传递的委托选项中设置 DEBUG_LEVEL=2
      • 为此、可以使用 DEBUG_LEVEL 设置向 MODEL_CONFIG 条目添加"optional_options"字典、或在 common_utils.py 中全局设置 DEBUG_LEVEL
    • `export TIDL_RT_DEBUG=1`

    BR、
    Reese