深度学习模型部署:REST API、ONNX 与服务化

FreeGuideOnline 最新 2026-06-17

深度学习模型部署:从训练到生产服务

引言:为什么部署如此重要?

训练出一个高精度的深度学习模型只是第一步,真正的价值在于让模型在生产环境中运行,对外提供稳定、高效的服务。模型部署涉及格式转换、推理优化、接口封装、运维监控等多个环节。本教程聚焦两大核心技术——ONNX 跨框架交换REST API 服务化,帮你快速构建可落地的在线推理服务。


部署前准备:模型导出与格式选择

导出训练好的模型权重

无论你使用 PyTorch、TensorFlow 还是其他框架,都需要先将模型的结构与权重保存为可迁移的文件。

  • PyTorch:保存 state_dict 或完整的模型(推荐导出为 torch.jit.scripttorch.onnx)。
  • TensorFlow:使用 SavedModel 格式导出(包含计算图和变量),兼容 TensorFlow Serving。

示范代码(PyTorch → ONNX)

import torch
import torchvision.models as models

model = models.resnet18(pretrained=True)
model.eval()

dummy_input = torch.randn(1, 3, 224, 224)

torch.onnx.export(
    model,
    dummy_input,
    "resnet18.onnx",
    input_names=["input"],
    output_names=["output"],
    dynamic_axes={"input": {0: "batch_size"}, "output": {0: "batch_size"}}
)

为什么要用 ONNX?

ONNX(Open Neural Network Exchange) 是一个开放格式,允许你在不同框架间迁移模型,同时它还是众多部署引擎的“通行语言”。
使用 ONNX 的核心优势:

  • 跨框架兼容:一个模型可在 PyTorch 训练,通过 ONNX 在 TensorRT 上加速推理。
  • 硬件优化入口:ONNX Runtime、TensorRT、OpenVINO 等引擎都原生支持 ONNX。
  • 标准化中间表示:便于团队协作、模型交付和后端解耦。

核心技能一:ONNX 模型的操作与优化

ONNX 模型验证与可视化

导出后必须验证 ONNX 模型的结构是否正确。

import onnx
model = onnx.load("resnet18.onnx")
onnx.checker.check_model(model)  # 通过检查则无异常
print(onnx.helper.printable_graph(model.graph))

使用 Netron 可视化模型结构,直观查看算子拓扑。

算子兼容性与版本调整

不同框架导出的 ONNX 可能包含目标引擎不支持的算子(opset)。可升级或降级 Opset 版本:

from onnx import version_converter
model = onnx.load("old_version.onnx")
converted_model = version_converter.convert_version(model, target_version=13)
onnx.save(converted_model, "new_version.onnx")

如果存在私有算子,可使用自定义算子注册功能。

使用 ONNX Runtime 执行推理

ONNX Runtime 是微软维护的高性能推理引擎,支持 CPU、GPU 等多种执行提供器。

import onnxruntime
import numpy as np

session = onnxruntime.InferenceSession("resnet18.onnx", providers=["CPUExecutionProvider"])
input_name = session.get_inputs()[0].name
output_name = session.get_outputs()[0].name

# 模拟输入
input_data = np.random.randn(1, 3, 224, 224).astype(np.float32)
result = session.run([output_name], {input_name: input_data})

性能优化技巧

  • 开启图优化:session_options.graph_optimization_level = onnxruntime.GraphOptimizationLevel.ORT_ENABLE_ALL
  • 使用 GPU 提供器:providers=["CUDAExecutionProvider"](需安装 onnxruntime-gpu)
  • 将模型转换为 FP16 或 INT8 量化版本以提升速度

核心技能二:将模型包装为 REST API 服务

在线推理最常用的服务化方式是 REST API,使用轻量级 Web 框架(如 Flask、FastAPI)将模型推理封装成 HTTP 接口。

使用 FastAPI 构建推理服务

FastAPI 性能优异且自动生成 API 文档,适合部署场景。

完整示例:图像分类服务

from fastapi import FastAPI, UploadFile, File
from PIL import Image
import onnxruntime
import numpy as np
from torchvision import transforms
import io

app = FastAPI(title="图像分类服务")

# 加载 ONNX 模型
session = onnxruntime.InferenceSession("resnet18.onnx")
input_name = session.get_inputs()[0].name
output_name = session.get_outputs()[0].name

# 与训练时保持一致的预处理
preprocess = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

@app.post("/predict")
async def predict(file: UploadFile = File(...)):
    image_bytes = await file.read()
    image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
    input_tensor = preprocess(image).unsqueeze(0).numpy()  # 增加 batch 维度

    outputs = session.run([output_name], {input_name: input_tensor})
    predicted_class = int(np.argmax(outputs[0]))
    return {"class_id": predicted_class, "probabilities": outputs[0].tolist()}

# 启动:uvicorn main:app --host 0.0.0.0 --port 8000

请求验证与错误处理

生产环境中必须添加健壮性设计:

  • 校验文件类型与大小(FastAPI 的 File 可限制)
  • 捕获推理异常并返回标准错误码
  • 日志记录(使用 logging 模块)

并发与性能调优

  • 异步处理:FastAPI 的 async def 本身释放 GIL,但 ONNX Runtime 的推理是同步的。可结合 run_in_executor 将推理放到线程池中防止阻塞事件循环。
  • 批量推理:对于 GPU 推理,应尽可能合并请求,使用 time.sleep 微批处理或专用框架(如 TorchServe 的动态 batch)。
  • 模型缓存:在服务启动时加载模型,避免请求过程中重加载。

服务化进阶:完整的部署架构

容器化部署

使用 Docker 统一运行环境,确保一致性。

Dockerfile 示例

FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

构建并运行:

docker build -t image-classifier .
docker run -p 8000:8000 image-classifier

服务编排与水平扩展

  • 使用 KubernetesDocker Swarm 管理多个服务实例。
  • 在前端放置 Nginx 或 API 网关负载均衡。
  • 搭配 Redis 缓存热点结果,减少模型调用次数。

监控与日志

  • 接入 Prometheus + Grafana 监控请求延迟、错误率、吞吐量。
  • 使用 ELK(Elasticsearch, Logstash, Kibana)集中管理日志。

常见工具链对比

工具/平台 适用场景 优势
Flask/FastAPI 轻量级自定义 API 灵活、易于集成 Python 生态
TorchServe PyTorch 模型专用 开箱即用的模型版本管理与批处理
TensorFlow Serving TensorFlow/SavedModel 原生支持 高性能,支持模型热更新
ONNX Runtime 跨框架标准推理 多硬件后端,轻量无框架依赖
Triton Inference Server 大规模生产级部署 支持多种框架,动态批处理,GPU 优化

实战练习:部署一个情感分析服务

  1. 下载预训练模型:选择一个文本情感分析模型(如 BERT tiny),将其转换为 ONNX。
  2. 编写 FastAPI 服务:接收文本输入,返回正面/负面概率。
  3. 添加预处理:分词、padding、attention_mask 生成。
  4. 容器化并本地测试:使用 curl 发送请求验证。
  5. 压力测试:使用 locustwrk 评估性能。

总结与下一步

通过本教程,你已掌握深度学习模型部署的核心流程:模型导出 → ONNX 转换与优化 → 基于 FastAPI 的 REST 服务封装 → 容器化交付。这只是起点,实际生产还需要关注安全认证、A/B 测试、模型版本管理等。
建议继续学习:

  • 模型量化与压缩(加速推理)
  • TensorRT 优化
  • 边缘设备部署(如 ONNX + NCNN)

将你的模型变成人人都能调用的 API,让 AI 真正落地!