在 SDK 版本 26 中。ethosu_apps_rpmsg 没有显示从 ethosu 获取结果的方法。
怎么做?
推理结果位于传递给作业的OFM 缓冲区中——即构造函数中的 ofm。expectedOutput 仅适用于 SDK 示例的验证路径;它不是计算结果的返回位置。i.MX93 Ethos-U 流程将完成的推理结果写入输出特征图缓冲区,并且在 Linux/RPMSg 流程中,在 OFM 填充后将响应发送回 Cortex-A。
对于你的代码来说,最重要的部分是:
InferenceProcess::InferenceJob job(
“工作”
网络模型
ifm,
ofm, // <-- 输出缓冲区
expectedOutput, // <-- 参考/验证数据,而非结果
pmuEventConfig,
0,
ðosu_drv,
0,
nullptr,
0,
0,
错误的);
job.invalidate();
bool failed = inferenceprocess.runJob(job);
job.clean();
如果(!失败)
{
// 从 ofm 读取结果
}
从概念上讲:
复制
如果(!失败)
{
// 输出张量 0
uint8_t *outputData = ofm[0].data();
size_t outputSize = ofm[0].size();
for (size_t i = 0; i < outputSize; i++)
{
PRINTF("ofm[%u] = %d\r\n", i, outputData[i]);
}
}
根据 ofm 的具体 SDK 类型,访问方式可能会略有不同,但规则相同:从传递给 InferenceJob 的同一个 ofm 缓冲区读取。
如果您的模型输出是量化的,则 ofm 中的字节通常是 int8_t 或 uint8_t,而不是最终的浮点值。使用输出张量的量化参数进行转换:
float real_value = (quantized_value - zero_point) * scale;
例如,对于 int8 输出:
int8_t *out = reinterpret_cast
for (size_t i = 0; i < outputSize; i++)
{
float y = (static_cast
PRINTF("out[%u] q=%d real=%f\r\n", i, out[i], y);
}
以RPMsg为例,请记住 ethosu_apps_rpmsg 主要是一个 Cortex-M33 固件服务。它接收来自 Cortex-A 的请求,运行 Ethos-U 作业,将结果写入 OFM 缓冲区,并通过 RPMsg 返回响应。在 Cortex-A/Linux 端,记录的 API 路径是访问 OFM 缓冲区,例如 inf->getOfmBuffers()。
所以:
您的计算结果已在 ofm 中;成功运行 runJob(job) 后,读取 ofm[0] 并根据模型的输出张量类型对其进行解释/反量化。