4. 模型服务化部署:从序列化到推理服务
模型服务化部署是将训练好的机器学习模型转化为可对外提供实时推理接口的过程。本章围绕三个核心环节展开:模型序列化(ONNX / PMML)、模型容器化(Docker)以及模型推理服务(Triton / TensorFlow Serving)。
核心目标:实现模型格式标准化、环境依赖隔离化、推理接口高效化,为实时监测系统提供低延迟、高吞吐的模型服务能力。
4.1 模型序列化:ONNX 与 PMML
模型序列化是将训练框架(PyTorch、TensorFlow、Scikit-learn 等)中的模型对象转换为标准中间表示格式的过程。标准格式可以跨框架、跨平台加载和推理,是服务化部署的前提。
| 特性 | ONNX(Open Neural Network Exchange) | PMML(Predictive Model Markup Language) |
|---|---|---|
| 适用场景 | 深度学习模型(CNN、RNN、Transformer) | 传统机器学习模型(决策树、回归、随机森林) |
| 格式类型 | 二进制 protobuf(.onnx) | XML 文本(.pmml) |
| 算子支持 | 丰富的神经网络算子,支持动态图导出 | 统计模型算子,不支持深度学习层 |
| 推理优化 | 支持量化、图优化、TensorRT 集成 | 无运行时优化,依赖解析器 |
| 跨平台能力 | 强(CPU / GPU / 边缘设备) | 中(主要面向 Java 和 Spark 生态) |
4.1.1 ONNX 导出示例(PyTorch → ONNX)
import torch
import torchvision.models as models
# 加载预训练模型
model = models.resnet18(pretrained=True)
model.eval()
# 构造示例输入
dummy_input = torch.randn(1, 3, 224, 224)
# 导出 ONNX
torch.onnx.export(
model,
dummy_input,
"resnet18.onnx",
input_names=["input"],
output_names=["output"],
dynamic_axes={"input": {0: "batch_size"}, "output": {0: "batch_size"}},
opset_version=17
)
print("ONNX 模型导出完成:resnet18.onnx")
4.1.2 PMML 导出示例(Scikit-learn → PMML)
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
from sklearn2pmml import sklearn2pmml
from sklearn2pmml.pipeline import PMMLPipeline
# 训练模型
iris = load_iris()
pipeline = PMMLPipeline([
("classifier", RandomForestClassifier(n_estimators=100))
])
pipeline.fit(iris.data, iris.target)
# 导出 PMML
sklearn2pmml(pipeline, "iris_rf.pmml", with_repr=True)
print("PMML 模型导出完成:iris_rf.pmml")
注意:ONNX 导出时需确认算子版本兼容性;PMML 导出时需确保特征名称与训练时一致,否则推理阶段会出现特征映射错误。
4.2 模型容器化:Docker 镜像构建
容器化将模型文件、运行时依赖、推理服务代码打包为独立镜像,确保开发、测试、生产环境一致。Docker 是当前最主流的容器引擎。
4.2.1 Dockerfile 最佳实践
# 基础镜像:选择轻量级 Python 运行时
FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 安装系统依赖(最小化)
RUN apt-get update && apt-get install -y --no-install-recommends \
libgomp1 \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件并安装 Python 包
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制模型文件和推理代码
COPY model.onnx .
COPY inference_server.py .
# 暴露服务端口
EXPOSE 8000
# 启动命令
CMD ["python", "inference_server.py"]
4.2.2 多阶段构建(减小镜像体积)
# 第一阶段:编译依赖
FROM python:3.9-slim AS builder
WORKDIR /build
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
# 第二阶段:运行镜像
FROM python:3.9-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY model.onnx .
COPY inference_server.py .
ENV PATH=/root/.local/bin:$PATH
EXPOSE 8000
CMD ["python", "inference_server.py"]
容器化关键指标:
- 镜像体积:控制在 500MB 以内,优先使用 slim 或 alpine 基础镜像
- 层数优化:合并 RUN 指令,减少镜像层数
- 安全扫描:使用 trivy / docker scan 检查已知漏洞
- 健康检查:添加 HEALTHCHECK 指令,确保容器可自愈
4.3 模型推理服务:Triton 与 TensorFlow Serving
推理服务框架提供高性能的模型加载、请求路由、批处理、版本管理等功能,是生产级部署的核心组件。
| 特性 | Triton Inference Server | TensorFlow Serving |
|---|---|---|
| 框架支持 | ONNX、TensorFlow、PyTorch、TensorRT、自定义后端 | TensorFlow(SavedModel)、TensorFlow Lite |
| 协议支持 | HTTP / gRPC / 原生 C API | HTTP / gRPC |
| 动态批处理 | 支持(延迟与吞吐量可配置) | 支持(需配置 batching_parameters) |
| 模型版本管理 | 基于目录结构自动管理 | 基于目录结构自动管理 |
| GPU 加速 | 原生支持多 GPU、MPS、CUDA 图 | 支持 GPU,但灵活性较低 |
| 自定义算子 | 支持 Python / C++ 自定义后端 | 需编译自定义 op |
4.3.1 Triton 模型仓库结构
model_repository/
├── resnet18/
│ ├── 1/ # 版本号目录
│ │ └── model.onnx # 序列化模型文件
│ └── config.pbtxt # 模型配置(可选)
├── bert_qa/
│ ├── 1/
│ │ ├── model.onnx
│ │ └── vocab.txt
│ └── config.pbtxt
└── ensemble_model/ # 组合模型
├── 1/
└── config.pbtxt
4.3.2 启动 Triton 服务(Docker)
docker run --gpus all --rm \
-p 8000:8000 -p 8001:8001 -p 8002:8002 \
-v /path/to/model_repository:/models \
nvcr.io/nvidia/tritonserver:23.10-py3 \
tritonserver --model-repository=/models
4.3.3 客户端调用示例(Python + gRPC)
import tritonclient.grpc as grpcclient
# 创建客户端连接
client = grpcclient.InferenceServerClient(url="localhost:8001")
# 构造输入
input_data = grpcclient.InferInput("input", [1, 3, 224, 224], "FP32")
input_data.set_data_from_numpy(preprocessed_image)
# 构造输出
output = grpcclient.InferRequestedOutput("output")
# 执行推理
result = client.infer(
model_name="resnet18",
inputs=[input_data],
outputs=[output]
)
# 获取结果
predictions = result.as_numpy("output")
print(predictions)
生产建议:
- 使用 gRPC 协议获得更低延迟(相比 HTTP 减少 30-50% 延迟)
- 开启动态批处理(Dynamic Batching)提升吞吐量
- 为每个模型配置独立的 instance_group 数量,避免资源争抢
- 使用 Prometheus 指标监控推理延迟和吞吐量
4.4 本章小结
- 模型序列化是服务化部署的起点:深度学习模型优先选择 ONNX,传统 ML 模型选择 PMML。
- 容器化保证环境一致性:使用多阶段构建、最小基础镜像、安全扫描来优化镜像质量。
- 推理服务框架提供生产级能力:Triton 支持多框架、多协议、动态批处理,适合复杂场景;TensorFlow Serving 适合纯 TensorFlow 生态。
- 部署流程:训练 → 序列化 → 容器化 → 推理服务 → 客户端调用,形成完整的模型服务化链路。
下一阶段准备:完成模型服务化部署后,需要配置 Prometheus + Grafana 监控推理延迟、吞吐量、GPU 利用率等指标,并设置告警规则。这部分内容将在第 5 章“实时监测与告警”中详细展开。