该选bentoml当需快速复现、版本化、kubernetes一键部署模型;选fastapi+onnx当已有成熟工程且需强定制路由/中间件/鉴权等逻辑。

什么时候该选 BentoML 而不是 FastAPI + ONNX 手写服务
BentoML 本质是模型服务的“打包+部署”工具链,不是纯 HTTP 框架;FastAPI + ONNX 是手动搭服务的组合。如果你需要快速把训练好的 PyTorch/TensorFlow 模型转成可复现、可版本化、能一键部署到 Kubernetes 的服务,BentoML 是更省力的选择。反之,若你已有成熟 FastAPI 工程、只跑 ONNX 模型、且对请求头/中间件/路由逻辑有强定制需求(比如要鉴权+灰度+动态模型加载),手写反而更透明可控。
常见错误现象:ValueError: Model not found in BentoService bundle —— 多因 save() 时没把 ONNX 文件显式 add_model() 进去,或路径没用 self._model_path 统一管理。
- BentoML 会自动处理模型序列化、环境依赖锁定(
conda.yaml或pip_dependencies),FastAPI 不管这些 - ONNXRuntime 在 BentoML 中需显式调用
onnxruntime.InferenceSession,不能直接torch.load() - BentoML 的
predict()方法签名必须严格匹配 API 输入输出,FastAPI 可自由定义 Pydantic model
ONNX 模型在 BentoML 里怎么加载才不崩
BentoML 不内置 ONNX 支持,得自己封装 InferenceSession。关键点是:ONNX 文件必须随 bundle 一起打包,且 session 初始化不能放在 __init__ 里(否则多进程下会冲突),而要懒加载或用 @property 缓存。
使用场景:模型较大(>500MB)、GPU 推理、需设置 providers=['CUDAExecutionProvider']。
立即学习“Python免费学习笔记(深入)”;
- 在
__init__中只存路径:self.model_path = self._model_path - 首次
predict()时才初始化 session:self._session = onnxruntime.InferenceSession(self.model_path, providers=...) - 避免在
__init__里调onnxruntime.set_default_logger_severity(3),它会影响全局日志级别 - Windows 下路径分隔符要用
os.path.join,别硬写"models\model.onnx"
FastAPI + ONNX 手写服务时,哪些参数容易被忽略
手写服务看似自由,但 ONNXRuntime 的配置项一旦漏掉,性能可能差 3–5 倍,尤其在并发请求下。
常见错误现象:onnxruntime.capi.onnxruntime_pybind11_state.InvalidArgument: Invalid argument: Input name ... not found —— 多因输入名和 ONNX 模型实际 input name 不一致,或没传 input_feed 字典。
-
sess_options.graph_optimization_level = onnxruntime.GraphOptimizationLevel.ORT_ENABLE_EXTENDED必开,否则跳过很多图优化 -
sess_options.intra_op_num_threads = 1(CPU 场景)防线程争抢,比默认值更稳 - 输入必须严格按
session.get_inputs()[0].name取名,不能硬编码"input" - Batch 推理时,
np.expand_dims()忘加 batch 维度,会导致 shape mismatch 错误
BentoML build 后的 bundle 怎么验证 ONNX 推理结果
build 出来的 bentoml build 结果不是黑盒,可以直接 import 并本地调用 predict(),比起 curl 测试更快更准。
性能影响:本地验证用 cpu provider 即可,但若目标部署环境是 GPU,务必在同环境验证 CUDAExecutionProvider 是否真生效(查 session.get_providers() 返回值)。
- 用
bentoml get <svc_name>:latest --print-json</svc_name>查 bundle 路径 - 进 bundle 目录,
python -c "from my_svc import MyBentoService; s = MyBentoService(); print(s.predict(...))" - 验证前先
import onnxruntime,确保没因环境隔离导致 ORT 没装上 - 别依赖
bentoml serve日志判断成功——它可能把print()和异常混在一起,直接调方法更可靠
真正麻烦的是模型输入预处理逻辑分散在训练脚本、BentoML 的 predict()、FastAPI 的 Pydantic validator 里,三处不一致就会静默出错。这点没人帮你校验,得自己写 assert 对齐。










