HZNU OS Lab

第四章副本 · 加载预训练模型

一个可能没有 AI 很难,但是会用 AI 则很简单的实验?可以尝试一下!

使用大语言模型

如果你遇到了麻烦,请向大语言模型求助,你也可以使用类似 CursorTraeTrae CNClaude CodeKimi CodeCodex 等工具可以获得强得多的编程智能。

在该实验中,你需要比在 Exp2 更进一步,你需要直接使用 ONNX Runtime 加载预训练的 CNN 模型,用于和前几个小实验一样的滤波任务。

链接库

本实验仓库样板代码只提供了 Linux x64macOS arm64 两个版本。

如果你要在 Windows 裸机上完成这个实验,你需要访问 ONNX Runtime Releases 页面下载对应的库并修改 Makefile 和相关文件。

你可以使用链接下载预训练模型:model.fp32.onnx,或在线下拷贝获得。

如果你懒得做这个实验,也可以看看支线实验中的插曲一 · 卷积图像修复网络和 OS 没什么关系。我在其中介绍了机器学习神经网络的基本概念,希望你可以有所收获。如果你对理论也不感兴趣,你或许也可以看看训练代码实验过程与代码解析,只从代码中就可以学习训练神经网络模型基本的流程,如果你可以对它(ResNet)做出性能改进,你将可以取得本次实验的基本满分

这部分没有和前文一样贴心的教程,从这开始换人了,根据任课老师的建议,本部分从原本的只需要调用一个函数就能获得 10 分,变成了一个相对复杂的题目。如果你打算询问 AI,我强烈建议你使用一个可以自己阅读本地文件的 IDE 或者 CLI(如本篇开头所说),使用 Web 上的 AI 聊天对本实验可能仍然有一定难度。

概览

以下给出一些基本的提示参考资料,你可以通过任何方式,搜寻,扩充,理解,复用这些内容;除抄袭外,方法不限。你也可以比较一下将参考资料和基本思路告诉大语言模型,相比直接询问有多大的提升

定位路径

src/ch4x/filter_cnn.c

/**
 * TODO:
 * Decide how the program locates the ONNX model file.
 *
 * Suggested directions:
 * - hard-code a repo-relative path while you are experimenting
 * - keep the path in one place so it is easy to change later
 * - return NULL when the model path has not been configured yet
 */
static const char* cnn_model_path(void) {
  return NULL;
}

嗯,没有什么难度的,只需要返回一个路径即可。关于这里的「Suggested directions」,可以减少大语言模型犯错的概率,事实上,如果你知道一个修改的大致方向,你应该明确的和这些 LLM 指出。

如果你有很多的想法,你其实可以和大语言模型讨论实现之间的好坏,而不是把一个不好的直接发给它,并让它自己修改;和 LLM 聊聊,或许你还能学到更多。

Lab Note
修改 filter_cnn.c,让它可以找到模型文件。

创建可复用的 Session

src/ch4x/onnx_inference.c 中的 onnx_session_create() 函数

session = (OnnxSession*)calloc(1, sizeof(OnnxSession));
if (session == NULL) {
  set_last_error("failed to allocate ONNX session");
  return NULL;
}

/*
* TODO:
* Build the ONNX Runtime session here.
*
* A typical implementation needs few steps,
* you should setup environment, create session,
* setting device and somehow IO.
*
* You are required to make inference on your CPU.
*/

set_last_error("TODO: implement onnx_session_create in src/ch4x/onnx_inference.c");
free(session);
return NULL;

以下是一些可能的参考资料,如果你有时间,可以自行阅读前两篇,其中包含了完成这部分代码的几乎全部内容;当然,你也可以直接把这两个链接交给 AI,取决于你的选择。

Lab Note

使用 ONNX Runtime 官方库,创建一个用于执行模型推理Session

从 ImageBuffer 到输入张量

src/ch4x/onnx_inference.c 中的 onnx_run_inference() 函数

/*
* TODO:
* Prepare the input image data for the model and perform inference,
* then convert the model output back to the output image buffer.
*
* You will need to:
* - Transform the raw image bytes into the tensor format the model expects
* - Execute the model using the prepared session
* - Extract and post-process the result tensor into 8-bit image data
*
* On any error:
* - Use set_last_error() with a descriptive message
* - Clean up any temporary resources you allocated
* - Return -1
*
* Keep resource management careful to avoid leaks.
*/

set_last_error("TODO: implement onnx_run_inference in src/ch4x/onnx_inference.c");
return -1;

除了上个步骤提供的参考资料外,再提供一个比较相关的示例代码

你也可以和 AI 讨论一些其他的解决方案,或者也可以仔细询问关于张量格式的概念?

布局

HWC(也叫 NHWC,当加上 Batch 维度时)是最常见的像素优先布局:

  • 外层是高度(Height) → 每一行
  • 中间是宽度(Width) → 每一列
  • 最内层是通道(Channel),对于 RGB 图像通常是 R、G、B 三个值连续存储

自行了解一下 CHW 布局?以及图片到张量的转化?

Lab Note

ImageBuffer 类型数据调整为适合 ONNX Runtime 加载的数据结构(张量)。

评估

复用在前几个小实验写的 SSIM 代码和 PSNR 计算过程,量化模型性能。

Lab Note

你需要使用在之前实验完成的 SSIM 及原本的 PSNR 指标评估它的性能,并计算增益。

Lab Note

提交作业时, 使用 make submit, 该命令会将 src 文件夹统一打包成 submit.tar.gz

同时需要将 output/ch4x/metrics.csv 放在同一个文件夹内, 文件名为 metrics.csv.

接下来可以开始支线实验 1,其介绍了机器学习神经网络的基本概念,并给出了训练本实验中预训练模型的代码。

本文作者