Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ACT 模型在 StarryOS/QEMU 上的部署全过程总结

​ 本文档总结当前的 ACT 模型部署流程。当前目标是把 PyTorch 训练得到的 ACT 模型导出为 ONNX,然后使用 ONNX Runtime在 StarryOS/QEMU/RISC-V 环境中完成推理。

整体流程:

PyTorch ACT 模型
-> 导出 ONNX
-> 准备 float32 输入数据
-> 交叉编译 ONNX Runtime RISC-V 动态库
-> 编写 C 语言 ONNX Runtime 推理程序
-> 交叉编译 C 程序为 RISC-V 可执行文件
-> 给 StarryOS 增加 /proc 内存统计补丁
-> 写入 StarryOS rootfs
-> 在 QEMU/StarryOS 中执行 ACT 推理并统计时间、内存、可执行文件大小

文档结构:

一、当前目录结构
二、模型导出为 ONNX
三、输入数据处理
四、交叉编译 ONNX Runtime
五、C 语言推理程序
六、交叉编译 C 推理程序
七、写入 StarryOS 镜像
八、在 StarryOS/QEMU 中运行
九、StarryOS /proc 内存统计补丁
十、StarryOS/QEMU 实验结果

当前 StarryOS 中跑通的输出形式:

ACT ONNX C inference start
model: /root/act/act.onnx
ORT version: 1.26.0
ONNX C output shape: [1, 8, 3]
first step: left_vel=+0.006228 | right_vel=-0.000566 | gripper_target=-0.000000

一、当前目录结构

当前的 GitHub 提交仓库目录为:

/home/czw1/clean-repos/proj57-complete-clean
├── README.md
├── docs/
│   └── images/
│       └── left_turn_inference_result.png
└── qemu_act_experiment/
    ├── QEMU_ACT_FULL_FLOW.md
    ├── build_ort_riscv64_musl.sh
    ├── install_build_helpers.sh
    ├── scripts/
    │   └── export_onnx.py
    ├── models/
    │   └── .gitignore
    ├── data/
    │   ├── frame_000001.jpg
    │   ├── frame_000227.jpg
    │   └── stats.json
    ├── c_onnx/
    │   ├── act_onnx_c.c
    │   ├── prepare_inputs.py
    │   ├── prepare_left_turn_inputs.py
    │   ├── input_bins/
    │   │   ├── image_1x1x3x224x224.bin
    │   │   ├── state_1x2.bin
    │   │   ├── action_q01_3.bin
    │   │   └── action_q99_3.bin
    │   └── input_bins_left_turn/
    │       ├── image_1x1x3x224x224.bin
    │       ├── state_1x2.bin
    │       ├── action_q01_3.bin
    │       └── action_q99_3.bin
    ├── runtime_libs/
    │   └── riscv64/
    │       ├── libonnxruntime.so.1
    │       ├── libatomic.so.1
    │       ├── libstdc++.so.6
    │       └── libgcc_s.so.1
    └── starryos_memstat_patch/
        ├── README.md
        └── kernel/src/
            ├── task/memstat.rs
            ├── task/mod.rs
            └── pseudofs/proc.rs

StarryOS 中的部署目录:

/root/act
├── act.onnx
├── act_onnx_c_riscv64
└── input_bins/
    ├── image_1x1x3x224x224.bin
    ├── state_1x2.bin
    ├── action_q01_3.bin
    └── action_q99_3.bin

StarryOS 中的运行时动态库目录:

/lib/libonnxruntime.so.1
/lib/libatomic.so.1
/lib/libstdc++.so.6
/lib/libgcc_s.so.1

二、模型导出为 ONNX

​ 原始模型是 PyTorch 的 model.pt。StarryOS 上不部署 PyTorch,而是部署 ONNX Runtime,所以需要先把 PyTorch 模型导出成 ONNX。

导出脚本:

/home/czw1/proj57-work/proj57/qemu_act_experiment/scripts/export_onnx.py

核心导出逻辑:

torch.onnx.export(
    wrapper,
    (dummy_image, dummy_state),
    ONNX_PATH,
    input_names=["image", "state"],
    output_names=["action"],
    opset_version=17,
    do_constant_folding=True,
    dynamo=False,
)

导出结果:

/home/czw1/proj57-work/proj57/qemu_act_experiment/models/act.onnx

三、输入数据处理

当前 C 语言推理程序不直接处理 JPEG 图片、JSON 文件和归一化逻辑,而是先用 Python 把输入转换成 float32 二进制文件。

输入处理脚本:

/home/czw1/proj57-work/proj57/qemu_act_experiment/c_onnx/prepare_inputs.py

生成文件:

/home/czw1/proj57-work/proj57/qemu_act_experiment/c_onnx/input_bins/image_1x1x3x224x224.bin
/home/czw1/proj57-work/proj57/qemu_act_experiment/c_onnx/input_bins/state_1x2.bin
/home/czw1/proj57-work/proj57/qemu_act_experiment/c_onnx/input_bins/action_q01_3.bin
/home/czw1/proj57-work/proj57/qemu_act_experiment/c_onnx/input_bins/action_q99_3.bin

各文件含义:

image_1x1x3x224x224.bin
  预处理后的图片输入。
  类型是 float32。
  shape 是 [1, 1, 3, 224, 224]。
  含义是 [batch, camera, channel, height, width]。

state_1x2.bin
  归一化后的状态输入。
  类型是 float32。
  shape 是 [1, 2]。

action_q01_3.bin
  action 的 1% 分位数,用于反归一化。

action_q99_3.bin
  action 的 99% 分位数,用于反归一化。

反归一化公式:

real = (normalized + 1) / 2 * (q99 - q01) + q01

模型输出的 action 是归一化值,不是直接控制量。C 程序会用 action_q01/action_q99 把第一步动作还原为真实动作值。

四、交叉编译 ONNX Runtime

StarryOS/QEMU 的目标平台是 RISC-V,因此不能使用 x86_64 Linux 的 ONNX Runtime 动态库,需要交叉编译 RISC-V 版本。

ONNX Runtime 源码目录:

/home/czw1/ort-work/onnxruntime

交叉编译工具链:

/opt/riscv64-linux-musl-cross/bin/riscv64-linux-musl-gcc
/opt/riscv64-linux-musl-cross/bin/riscv64-linux-musl-g++

交叉编译脚本:(这里非常非常慢 给我的wsl2跑崩了一次 我的5070的电脑跑了半个多小时)

/home/czw1/proj57-work/proj57/qemu_act_experiment/build_ort_riscv64_musl.sh

编译出的 ONNX Runtime 主库:

/home/czw1/ort-work/onnxruntime/build/Linux/MinSizeRel/libonnxruntime.so.1.26.0

当前部署包中保存的 RISC-V 运行库:

/home/czw1/proj57-work/proj57/qemu_act_experiment/runtime_libs/riscv64/libonnxruntime.so.1
/home/czw1/proj57-work/proj57/qemu_act_experiment/runtime_libs/riscv64/libatomic.so.1
/home/czw1/proj57-work/proj57/qemu_act_experiment/runtime_libs/riscv64/libstdc++.so.6
/home/czw1/proj57-work/proj57/qemu_act_experiment/runtime_libs/riscv64/libgcc_s.so.1

这些动态库的作用:

libonnxruntime.so.1
  ONNX Runtime 主库,负责加载 ONNX 模型并执行推理。

libatomic.so.1
  原子操作运行库。RISC-V 上部分 atomic 操作需要它。

libstdc++.so.6
  C++ 标准库。虽然推理程序是 C 写的,但 ONNX Runtime 内部是 C++ 实现。

libgcc_s.so.1
  GCC 运行时库,提供底层运行时支持。

五、C 语言推理程序

当前正式使用的推理源码:

/home/czw1/proj57-work/proj57/qemu_act_experiment/c_onnx/act_onnx_c.c

该程序直接使用 ONNX Runtime C API:

#include <onnxruntime_c_api.h>

推理程序核心流程:

1. 拼出模型和输入文件路径。
2. 读取 image/state/action_q01/action_q99 四个 float32 bin 文件。
3. 通过 OrtGetApiBase()->GetApi(ORT_API_VERSION) 获取 ONNX Runtime C API 函数表。
4. 创建 OrtEnv。
5. 创建 OrtSessionOptions。
6. 加载 /root/act/act.onnx,创建 OrtSession。
7. 创建 image/state 输入 Tensor。
8. 调用 g_ort->Run(...) 执行推理。
9. 从 output_tensor 中取出 action。
10. 对第一步 action 做反归一化。
11. 打印 left_vel/right_vel/gripper_target。
12. 释放 ONNX Runtime 对象和 malloc 内存。

输出 shape:

[1, 8, 3]

含义:

1 = batch size
8 = 一次预测未来 8 个动作步
3 = 每步 3 个动作值

动作维度:

left_vel
right_vel
gripper_target

第一步动作对应:

action[0] = 第 1 步 left_vel
action[1] = 第 1 步 right_vel
action[2] = 第 1 步 gripper_target

六、交叉编译 C 推理程序

进入 C 推理目录:

cd ~/proj57-work/proj57/qemu_act_experiment/c_onnx

交叉编译命令:

/opt/riscv64-linux-musl-cross/bin/riscv64-linux-musl-gcc \
  -O2 \
  -no-pie \
  act_onnx_c.c \
  -I/home/czw1/ort-work/onnxruntime/include/onnxruntime/core/session \
  -L/home/czw1/ort-work/onnxruntime/build/Linux/MinSizeRel \
  -lonnxruntime \
  -Wl,-rpath,/lib \
  -o act_onnx_c_riscv64

检查编译结果:

file act_onnx_c_riscv64
readelf -d act_onnx_c_riscv64 | grep NEEDED

正常应看到:

ELF 64-bit LSB executable, UCB RISC-V
NEEDED Shared library: [libonnxruntime.so.1]
NEEDED Shared library: [libc.so]

七、写入 StarryOS 镜像

StarryOS 镜像路径:

/home/czw1/starryos-work/StarryOS/make/disk.img

需要写入 StarryOS 的文件:

/root/act/act.onnx
/root/act/act_onnx_c_riscv64
/root/act/input_bins/image_1x1x3x224x224.bin
/root/act/input_bins/state_1x2.bin
/root/act/input_bins/action_q01_3.bin
/root/act/input_bins/action_q99_3.bin
/lib/libonnxruntime.so.1
/lib/libatomic.so.1
/lib/libstdc++.so.6
/lib/libgcc_s.so.1

写入方式是在 WSL2 中使用 debugfs 直接修改 StarryOS 的 ext4 镜像。

基本流程:

cd ~/starryos-work/StarryOS

e2fsck -f -y make/disk.img || true
debugfs -w -f install_commands.debugfs make/disk.img
e2fsck -f -y make/disk.img || true

命令含义:

e2fsck -f -y make/disk.img
  检查并修复 ext4 镜像。

debugfs -w -f install_commands.debugfs make/disk.img
  以写模式打开镜像,并根据命令文件写入部署文件。

再次 e2fsck
  写入完成后再次检查文件系统一致性。

八、在 StarryOS/QEMU 中运行

启动 StarryOS:

cd ~/starryos-work/StarryOS
make ARCH=riscv64 run

进入 StarryOS shell 后执行:

cd /root/act
./act_onnx_c_riscv64

成功输出示例:

ACT ONNX C inference start
model: /root/act/act.onnx
ORT version: 1.26.0
ONNX C output shape: [1, 8, 3]
first step: left_vel=+0.006228 | right_vel=-0.000566 | gripper_target=-0.000000

九、StarryOS /proc 内存统计补丁

​ 为了满足比赛文档中“运行时内存占用情况”的要求,本项目对 StarryOS 做了一个最小内核补丁,让 /proc/self/status 支持 Linux 风格的进程内存字段:

VmSize  进程虚拟内存映射总量
VmHWM   进程历史峰值常驻内存
VmRSS   进程当前常驻内存

补丁代码保存在:

qemu_act_experiment/starryos_memstat_patch/
├── README.md
└── kernel/src/
    ├── task/memstat.rs
    ├── task/mod.rs
    └── pseudofs/proc.rs

核心实现逻辑:memstat.rs 遍历进程地址空间中的 memory area,并逐页调用页表查询;能查到物理页的虚拟页计入 RSS。ProcessData 中新增 rss_high_water 用于记录峰值 RSS,proc.rs 在生成 /proc/[pid]/status 时输出 VmSize / VmHWM / VmRSS

构建验证命令:

cd ~/starryos-work/StarryOS
export PATH=/opt/riscv64-linux-musl-cross/bin:/home/czw1/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export RUSTFLAGS=-Awarnings
make ARCH=riscv64 build
make ARCH=riscv64 run

StarryOS 中验证:

cat /proc/self/status

已验证输出包含:

VmSize: 1996 kB
VmHWM:  376 kB
VmRSS:  376 kB

因此该补丁只增强 /proc 内存观测能力,不改变 ACT 模型推理逻辑。

十、StarryOS/QEMU 实验结果

本节记录在 StarryOS/QEMU 环境中使用同一个 ACT ONNX C 推理程序,对两张输入图片分别运行后的结果。两组实验只替换 input_bins 输入数据,模型文件、ONNX Runtime 动态库、C 推理程序保持一致。

待验证图片 frame_000227.jpg

frame_000227.jpg

待验证图片 frame_000001.jpg

frame_000001.jpg

实验环境:

OS: StarryOS on QEMU riscv64
Runtime: ONNX Runtime 1.26.0, CPUExecutionProvider
Program: /root/act/act_onnx_c_riscv64
Model: /root/act/act.onnx
Input shape: image [1, 1, 3, 224, 224], state [1, 2]
Output shape: action [1, 8, 3]

指标含义:

executable_size_bytes  RISC-V C 推理可执行文件大小
inference_time_ms      单次 OrtRun 推理耗时,不包含 StarryOS 启动时间
VmSize                 推理结束后进程虚拟地址空间大小
VmHWM                  推理过程中进程峰值常驻内存,作为内存占用主要指标
VmRSS                  推理结束时进程当前常驻内存

两组实验结果:

输入图片 输入目录 可执行文件大小 推理耗时 VmSize VmHWM 峰值内存 第一帧动作输出 结果说明
frame_000227.jpg qemu_act_experiment/c_onnx/input_bins 13056 bytes / 12.75 KB 16285.831 ms 229112 KB 218108 KB left_vel=+0.006228, right_vel=-0.000566, gripper_target=-0.000000 左轮速度大于右轮速度
frame_000001.jpg qemu_act_experiment/c_onnx/input_bins_left_turn 13056 bytes / 12.75 KB 17919.316 ms 229112 KB 218108 KB left_vel=-0.001547, right_vel=+0.007225, gripper_target=-0.000000 右轮速度大于左轮速度,符合左转趋势

StarryOS 终端输出示例:

ACT ONNX C inference start
model: /root/act/act.onnx
executable_size_bytes=13056
executable_size_kb=12.75
mem_start_kb: VmSize=16100 | VmHWM=2880 | VmRSS=2880
mem_after_read_inputs_kb: VmSize=16692 | VmHWM=3480 | VmRSS=3480
ORT version: 1.26.0
mem_after_create_session_kb: VmSize=220644 | VmHWM=212212 | VmRSS=212212
mem_before_run_kb: VmSize=220644 | VmHWM=212212 | VmRSS=212212
inference_time_ms=17919.316
mem_after_run_kb: VmSize=229112 | VmHWM=218108 | VmRSS=218108
ONNX C output shape: [1, 8, 3]
first step: left_vel=-0.001547 | right_vel=+0.007225 | gripper_target=-0.000000

本项目在文档撰写和问题排查方面使用 AI 编辑器辅助,但核心代码编写、流程设计、交叉编译、StarryOS/QEMU 部署和实验验证均由本人独立完成。

About

2026全国大学生操作系统大赛57题act算法部署

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages