4. 模型序列化与格式:ONNX、PMML、Pytorch/TensorFlow SavedModel、TensorRT
在贷后风险拦截场景中,模型训练完成后必须经过序列化与格式转换,才能部署到生产环境的推理引擎中。不同的序列化格式决定了模型的可移植性、推理性能以及跨平台兼容性。本章将深入剖析四种主流格式:ONNX、PMML、PyTorch/TensorFlow SavedModel 和 TensorRT,并给出在贷后拦截链路中的选型建议。
4.1 为什么需要模型序列化?
模型训练框架(如 PyTorch、TensorFlow)通常包含完整的计算图定义、优化器状态和训练辅助信息。生产推理环境不需要这些冗余信息,只需要前向计算图和权重参数。序列化的核心目标包括:
- 解耦训练与推理:训练环境使用 GPU 集群,推理环境可能使用 CPU、边缘设备或专用加速卡。
- 版本固化:冻结模型参数,避免因框架升级导致推理结果不一致。
- 性能优化:通过图优化、算子融合、量化等手段提升推理速度。
- 跨语言部署:Java、C++、Go 等生产语言无法直接加载 Python 训练的模型。
4.2 四种主流格式对比
| 格式 | 维护方 | 核心特点 | 适用场景 | 贷后拦截适配度 |
|---|---|---|---|---|
| ONNX | 微软 / Linux Foundation | 开放神经网络交换格式,支持跨框架转换,算子标准统一 | 跨框架部署、多平台推理(CPU/GPU/边缘) | ⭐⭐⭐⭐⭐ 推荐 |
| PMML | Data Mining Group | 基于 XML 的预测模型标记语言,支持树模型、线性模型、规则集 | 传统机器学习模型(XGBoost、LR、决策树)的 Java 部署 | ⭐⭐⭐⭐ 适合树模型 |
| SavedModel | Google / TensorFlow | TensorFlow 原生格式,包含 SignatureDef、Asset 文件,支持 TF Serving | 纯 TensorFlow 生态、TFX 流水线、TF Serving 部署 | ⭐⭐⭐ 生态绑定 |
| TensorRT | NVIDIA | NVIDIA 推理优化引擎,支持 FP16/INT8 量化、算子融合、动态张量 | GPU 高吞吐低延迟推理、批量打分 | ⭐⭐⭐⭐ 高吞吐场景 |
4.3 ONNX:跨框架互操作的基石
ONNX(Open Neural Network Exchange)定义了一套标准算子集和计算图表示。PyTorch 模型可通过 torch.onnx.export 导出,TensorFlow 模型可通过 tf2onnx 转换。贷后拦截模型通常包含 Embedding 层、Dense 层和 Sigmoid 输出,ONNX 对这些算子支持良好。
dynamic_axes 参数,使模型支持可变 batch size。贷后拦截请求的 batch size 可能从 1 到 256 不等,固定 batch size 会导致资源浪费或请求失败。
import torch
import torch.nn as nn
class RiskModel(nn.Module):
def __init__(self, input_dim=128):
super().__init__()
self.net = nn.Sequential(
nn.Linear(input_dim, 64),
nn.ReLU(),
nn.Dropout(0.2),
nn.Linear(64, 32),
nn.ReLU(),
nn.Linear(32, 1),
nn.Sigmoid()
)
def forward(self, x):
return self.net(x)
model = RiskModel()
model.eval()
dummy_input = torch.randn(1, 128)
torch.onnx.export(
model,
dummy_input,
"risk_model.onnx",
input_names=["features"],
output_names=["risk_score"],
dynamic_axes={
"features": {0: "batch_size"},
"risk_score": {0: "batch_size"}
},
opset_version=17
)
4.4 PMML:传统机器学习模型的 Java 部署利器
PMML(Predictive Model Markup Language)使用 XML 描述模型结构,天然适合 Java 生态。贷后拦截中常用的 XGBoost、LightGBM、逻辑回归模型均可导出为 PMML。通过 sklearn2pmml 或 jpmmml 库,可以在 Java 服务中直接加载并打分,无需启动 Python 进程。
from sklearn2pmml import sklearn2pmml
from sklearn.ensemble import GradientBoostingClassifier
from sklearn2pmml.pipeline import PMMLPipeline
pipeline = PMMLPipeline([
("classifier", GradientBoostingClassifier(n_estimators=100))
])
pipeline.fit(X_train, y_train)
sklearn2pmml(pipeline, "gbm_risk_model.pmml", with_repr=True)
4.5 PyTorch/TensorFlow SavedModel:原生生态的完整保存
SavedModel 是 TensorFlow 的推荐序列化格式,包含 saved_model.pb、变量文件和资产文件。它保留了模型的 SignatureDef,允许客户端指定输入/输出张量的名称和数据类型。PyTorch 的 torch.jit.script 和 torch.jit.trace 提供了类似功能,生成 TorchScript 格式。
在贷后拦截中,如果团队已经深度绑定 TensorFlow 生态(如使用 TFX 构建特征工程流水线),直接使用 SavedModel + TF Serving 是最省力的方案。但需要注意 TF Serving 的版本兼容性和资源开销。
4.6 TensorRT:GPU 推理的极致加速
TensorRT 是 NVIDIA 推出的推理优化引擎,支持将 ONNX 模型或 TensorFlow SavedModel 转换为 TensorRT 引擎(.plan 文件)。它通过以下技术实现加速:
- 算子融合:将多个小算子合并为单一 kernel,减少 kernel launch 开销。
- 精度校准:支持 FP16 和 INT8 量化,在几乎不损失精度的情况下将推理速度提升 2~4 倍。
- 动态张量:允许输入 shape 在运行时变化,避免多次构建引擎。
import tensorrt as trt
TRT_LOGGER = trt.Logger(trt.Logger.WARNING)
builder = trt.Builder(TRT_LOGGER)
network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH))
parser = trt.OnnxParser(network, TRT_LOGGER)
with open("risk_model.onnx", "rb") as f:
parser.parse(f.read())
config = builder.create_builder_config()
config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 << 30) # 1GB
config.set_flag(trt.BuilderFlag.FP16)
serialized_engine = builder.build_serialized_network(network, config)
with open("risk_model_fp16.plan", "wb") as f:
f.write(serialized_engine)
4.7 序列化格式选型决策流程
4.8 贷后拦截场景的序列化最佳实践
- 深度学习模型(DNN、Transformer):优先导出 ONNX,再根据推理硬件选择 ONNX Runtime(CPU/混合)或 TensorRT(GPU)。
- 树模型(XGBoost、LightGBM):如果团队 Java 技术栈成熟,使用 PMML 可避免跨语言调用开销;否则导出 ONNX(需 ONNX Runtime 1.12+ 支持树模型)。
- 混合模型(特征工程 + 深度网络):将特征工程部分用 PMML 或 Python 预处理,深度网络部分用 ONNX/TensorRT,通过微服务编排组合。
- 版本管理:每次模型更新时,同时保存 ONNX 和 TensorRT 引擎文件,并记录对应的框架版本和算子集版本,避免回滚时出现兼容性问题。
✅ 导出 ONNX 时验证算子版本与推理引擎兼容
✅ 使用
onnxruntime.quantization 对 ONNX 模型做动态量化(CPU 场景)✅ TensorRT 引擎构建时开启
sparsity 标志(如果模型训练时使用了结构化剪枝)✅ 对 PMML 模型进行 Java 端打分测试,确保浮点精度与 Python 端一致(误差 < 1e-5)
✅ 建立模型格式的 CI/CD 流水线,每次提交自动导出并验证推理结果