如何把训练好的机器学习模型部署为在线推理服务
notebook 里 AUC 0.92 的模型,离产生业务价值还差一条完整的服役链路:序列化、接口化、容器化、监控。**模型部署的本质是把”一次实验”变成”一个服务”**:有版本、有契约、有容量、有告警。本文用 scikit-learn + FastAPI + Docker 走通最小生产链路。
graph TD
A[训练脚本产出模型] --> B[序列化 + 元数据登记]
B --> C[FastAPI 包装推理接口]
C --> D[Docker 镜像固化环境]
D --> E[部署 + 健康检查]
E --> F{线上指标正常}
F -- 是 --> G[持续监控漂移]
F -- 否 --> H[回滚上一版本镜像]
前置准备
以一个已训练好的分类模型为例,安装服务化依赖:
pip install scikit-learn fastapi uvicorn joblib pydantic |
- joblib:sklearn 模型序列化事实标准
- pydantic:定义请求/响应契约,接口文档自动生成
步骤一:模型产物与元数据一起登记
只存 .pkl 是事故源头——半年后没人知道它用哪些特征、什么版本训练:
import joblib, json, sklearn |
- 文件名带版本号(v3),新模型不覆盖旧文件——回滚即换文件
feature_order是关键契约:线上特征必须按训练顺序组装
步骤二:FastAPI 包装推理接口
用 pydantic 把入参校验前置,非法请求不进模型:
from fastapi import FastAPI, HTTPException |
本地起服务验证:uvicorn serve:app --port 8000,打开 /docs 即得交互文档。
步骤三:容器化固化运行环境
“我本地能跑”的解药是镜像:Python 版本、依赖版本与模型文件一起冻结:
FROM python:3.11-slim |
docker build -t churn-model:v3 . && docker run -p 8000:8000 churn-model:v3 |
镜像 tag 与模型版本对齐(v3),部署平台按 tag 发布与回滚。
步骤四:上线监控与漂移检测
服务活着 ≠ 模型好用,监控要覆盖三层:
- 服务层:QPS、p99 延迟、错误率(/healthz 供探针)
- 输入层:特征分布 PSI > 0.2 告警——上游埋点改了的典型信号
- 输出层:预测分数分布漂移、正例率突变;无标签期用代理指标(如人工抽检一致率)
def psi(expected, actual, bins=10): |
常见问题
- 线上离线特征不一致(training-serving skew):特征组装逻辑抽成共享模块,训练与 serving 同代码路径
- sklearn 版本升级后加载报错:镜像冻结版本;升级 = 新模型重训 + 新镜像,不做原地升级
- 冷启动慢:模型加载放启动阶段(lifespan),就绪探针通过后才接流量
- 批量预测需求:另开
/predict_batch接口,复用同一模型实例,注意限流防 OOM - 反序列化安全红线:joblib/pickle 加载时会执行对象构造代码,等价于运行任意程序——只加载自己训练管线产出、存放于可信仓库的产物;对外交换的模型数据优先用 ONNX 等不带代码执行的格式,并校验文件哈希/签名
小结
模型服务化四步:产物带元数据登记(可追溯)、接口带契约校验(可调用)、镜像固化环境(可回滚)、三层监控(可运营)。链路搭好后,”上线一个新模型”就退化为一次配置变更:换镜像 tag、跑回归、灰度、全量——模型迭代速度取决于这条链路的自动化程度,而不是训练脚本。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 非鱼小站!
评论
WalineDisqus








