2. 环境搭建与工具链:工欲善其事,必先利其器
说实话,做ONNX模型精度验证,最怕的不是模型多复杂,而是环境没搭好。我见过太多同学花了两天时间调一个bug,最后发现是Python版本不对。所以这一章,咱们先把地基打牢。
2.1 Python环境配置:别小看这一步
我个人习惯用conda来管理环境。为什么?因为ONNX Runtime对Python版本有要求,不同版本之间可能不兼容。你想想看,要是因为Python版本问题导致模型跑不起来,那多冤。
具体操作很简单:
# 创建虚拟环境
conda create -n onnx_env python=3.9
# 激活环境
conda activate onnx_env
# 安装基础依赖
pip install numpy pandas matplotlib
嗯,这里要注意:numpy版本别太新。ONNX Runtime对numpy有版本限制,我建议用1.23.x或1.24.x。太新的版本可能会报错。
2.2 ONNX Runtime安装:CPU还是GPU?
ONNX Runtime有两种安装方式:CPU版本和GPU版本。怎么选?说白了,看你的场景。
| 场景 | 推荐版本 | 安装命令 |
|---|---|---|
| 模型验证、调试 | CPU版本 | pip install onnxruntime |
| 生产部署、推理加速 | GPU版本 | pip install onnxruntime-gpu |
| 边缘设备、嵌入式 | CPU版本(优化) | pip install onnxruntime-silicon |
我在项目中遇到过一个问题:GPU版本装上了,但推理速度反而比CPU慢。后来发现是CUDA版本不匹配。所以,装GPU版本前,先确认你的CUDA版本:
# 检查CUDA版本
nvcc --version
# 或者
nvidia-smi
2.3 Netron可视化工具:模型结构一目了然
Netron是我最常用的工具之一。它能可视化ONNX模型的结构,让你看到每一层的输入输出、参数信息。说白了,就是给模型拍个X光片。
安装方式有两种:
- 在线版:直接打开
https://netron.app,上传模型文件即可。 - 本地版:用pip安装,适合离线环境。
# 安装Netron
pip install netron
# 启动Netron
netron your_model.onnx
我个人习惯用本地版。为什么?因为模型文件可能很大,上传到在线版太慢。而且,有些模型涉及隐私,不适合上传。
打开Netron后,你会看到模型的结构图。每个节点代表一个算子,点击节点可以看到详细信息。我记得第一次用Netron时,发现一个模型有3000多个节点,当时就懵了。后来才知道,可以用搜索功能快速定位特定算子。
2.4 onnx-simplifier工具:给模型瘦身
ONNX模型有时候会包含一些冗余操作,比如恒等映射、多余的reshape。这些操作不会影响精度,但会增加模型大小和推理时间。onnx-simplifier就是用来干这个的。
安装很简单:
pip install onnx-simplifier
使用方式:
# 简化模型
python -m onnxsim your_model.onnx simplified_model.onnx
# 或者用Python API
import onnx
from onnxsim import simplify
model = onnx.load("your_model.onnx")
model_simplified, check = simplify(model)
onnx.save(model_simplified, "simplified_model.onnx")
你可能会问:简化后的模型精度会变吗?答案是:不会。onnx-simplifier只做等价变换,不会改变模型的数学计算。我在项目中测试过,简化后的模型推理结果和原模型完全一致。
另外,onnx-simplifier还有一个隐藏功能:它可以帮你检查模型是否支持ONNX Runtime。如果模型中有不支持的算子,simplifier会报错。这相当于一个兼容性检查。
2.5 环境验证:确保一切就绪
环境搭好后,最好做个快速验证。我一般会写一个简单的测试脚本:
import onnx
import onnxruntime as ort
import numpy as np
# 1. 检查ONNX版本
print(f"ONNX版本: {onnx.__version__}")
# 2. 检查ONNX Runtime版本
print(f"ONNX Runtime版本: {ort.__version__}")
# 3. 创建一个简单的模型并推理
import onnx.helper as helper
# 定义输入输出
X = helper.make_tensor_value_info('X', onnx.TensorProto.FLOAT, [1, 3])
Y = helper.make_tensor_value_info('Y', onnx.TensorProto.FLOAT, [1, 2])
# 定义节点(这里用Relu作为示例)
node = helper.make_node('Relu', ['X'], ['Y'])
# 创建模型
graph = helper.make_graph([node], 'test_graph', [X], [Y])
model = helper.make_model(graph)
# 保存并加载
onnx.save(model, 'test_model.onnx')
session = ort.InferenceSession('test_model.onnx')
# 推理测试
input_data = np.array([[1.0, -2.0, 3.0]], dtype=np.float32)
output = session.run(None, {'X': input_data})
print(f"推理结果: {output}")
如果这个脚本能正常运行,说明环境没问题。如果报错,那就根据错误信息排查。嗯,这里要注意:ONNX Runtime的版本和ONNX的版本要匹配。我建议用ONNX 1.14.x + ONNX Runtime 1.16.x的组合,这个组合比较稳定。
好了,环境搭建就到这里。下一章,我们会用这些工具来验证一个真实的模型。到时候,你会发现这些工具真的能帮你省不少时间。