1. 车载AI座舱环境搭建与交叉编译工具链配置
任务目标
在车载Linux系统(aarch64)上搭建AI推理环境,配置交叉编译工具链,并验证编译产物可在目标板上运行。本案例以ONNX Runtime为推理引擎,完成从x86主机交叉编译到aarch64目标板的完整闭环。
环境与依赖
- 主机:x86_64 Ubuntu 20.04+,已安装cmake(≥3.18)、gcc、git
- 目标板:aarch64 Linux(如NVIDIA Orin / 瑞芯微RK3588),root权限
- 交叉编译器:gcc-aarch64-linux-gnu(主机执行
sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu) - 推理引擎:ONNX Runtime v1.17.0(预编译aarch64包)
实现步骤
1. 获取ONNX Runtime交叉编译包
# 在主机下载aarch64版本(无需自行编译,节省数小时)
wget https://github.com/microsoft/onnxruntime/releases/download/v1.17.0/onnxruntime-linux-aarch64-1.17.0.tgz
tar -xzf onnxruntime-linux-aarch64-1.17.0.tgz
# 解压后目录结构:onnxruntime-linux-aarch64-1.17.0/{include,lib}
2. 编写交叉编译测试程序
创建文件 infer_test.cpp,实现一个最小推理验证:加载ONNX模型,执行一次前向计算,输出结果维度。
#include <onnxruntime_cxx_api.h>
#include <vector>
#include <iostream>
int main() {
// 创建环境(使用CPU EP)
Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "test");
Ort::SessionOptions session_options;
session_options.SetIntraOpNumThreads(1);
// 加载模型(模型文件与可执行文件同目录)
const char* model_path = "model.onnx";
Ort::Session session(env, model_path, session_options);
// 获取输入输出信息
Ort::AllocatorWithDefaultOptions allocator;
auto input_name = session.GetInputNameAllocated(0, allocator);
auto output_name = session.GetOutputNameAllocated(0, allocator);
// 构造输入数据(假设模型输入为 1x3x224x224 float)
std::vector<int64_t> input_shape = {1, 3, 224, 224};
std::vector<float> input_data(1 * 3 * 224 * 224, 0.5f);
// 创建输入输出Tensor
Ort::MemoryInfo memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
Ort::Value input_tensor = Ort::Value::CreateTensor<float>(
memory_info, input_data.data(), input_data.size(), input_shape.data(), input_shape.size());
// 运行推理
const char* input_names[] = {input_name.get()};
const char* output_names[] = {output_name.get()};
auto output_tensors = session.Run(Ort::RunOptions{nullptr}, input_names, &input_tensor, 1, output_names, 1);
// 获取输出维度
auto output_info = output_tensors[0].GetTensorTypeAndShapeInfo();
auto output_shape = output_info.GetShape();
std::cout << "Inference OK. Output dims: ";
for (auto d : output_shape) std::cout << d << " ";
std::cout << std::endl;
return 0;
}
3. 交叉编译
# 编译命令(使用aarch64交叉编译器)
aarch64-linux-gnu-g++ -std=c++17 infer_test.cpp \
-I onnxruntime-linux-aarch64-1.17.0/include \
-L onnxruntime-linux-aarch64-1.17.0/lib \
-lonnxruntime -o infer_test_arm
# 确认产物架构
file infer_test_arm
# 预期输出:ELF 64-bit LSB executable, ARM aarch64
4. 部署到目标板并运行
# 将可执行文件、模型、动态库拷贝到目标板(假设目标板IP为192.168.1.100)
scp infer_test_arm model.onnx user@192.168.1.100:/home/user/
scp onnxruntime-linux-aarch64-1.17.0/lib/libonnxruntime.so* user@192.168.1.100:/home/user/
# 在目标板上执行
ssh user@192.168.1.100
export LD_LIBRARY_PATH=/home/user:$LD_LIBRARY_PATH
chmod +x infer_test_arm
./infer_test_arm
验证方法
- 编译验证:
file infer_test_arm输出包含ARM aarch64,说明交叉编译成功 - 运行验证:目标板上执行后输出
Inference OK. Output dims: ...,且无动态库加载错误,说明推理环境搭建完成 - 判定标准:程序返回码为0,输出维度与模型实际输出维度一致(例如分类模型输出
1 1000)
常见问题
- 找不到libonnxruntime.so:确认目标板上
LD_LIBRARY_PATH包含库所在目录,且库文件权限可读 - 模型文件缺失:本案例需要准备一个ONNX格式模型(如ResNet50),放置在与可执行文件相同目录
- GLIBC版本不兼容:若目标板系统较旧,需使用目标板自带编译器重新编译ONNX Runtime源码(耗时较长,非本案例范围)