Course 2:模型部署与服务
课程简介
模型序列化、API 服务、边缘部署策略。
🎬 本课程视频:MLOps Production — 机器学习工程生产实践
一、模型序列化
1.1 模型持久化
模型训练完成后,需要将其保存到磁盘以便后续部署。这个过程称为模型序列化(Model Serialization)。
Python 最常用的序列化方式:
import joblib
# 保存模型
joblib.dump(model, 'model_v1.0.pkl')
# 加载模型
model = joblib.load('model_v1.0.pkl')
对于深度学习模型:
# PyTorch
torch.save(model.state_dict(), 'model_weights.pth')
# TensorFlow/Keras
model.save('tf_model/')
1.2 序列化格式对比
| 格式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| Pickle/Joblib | Scikit-learn 模型 | 简单易用 | 版本依赖问题 |
| ONNX | 跨框架部署 | 框架无关、支持优化 | 部分算子不支持 |
| TorchScript | PyTorch 生产部署 | 高性能、支持导出 | 图模式编程限制 |
| SavedModel | TensorFlow Serving | 完整模型格式 | 文件体积大 |
| PMML | 企业级跨平台 | 行业标准 | 现代模型支持差 |
1.3 模型与代码的版本匹配
一个重要但容易被忽略的问题:模型是在特定版本的依赖库下训练的,部署时需要用相同版本的库。
解决方案:
- Docker 容器化:将模型和依赖一起打包
- 环境锁定:记录所有依赖的精确版本号(requirements.txt)
- 模型注册表:在注册表中记录运行环境信息
二、API 服务
2.1 REST API 服务
最常见的模型部署方式是将模型封装为 REST API:
from flask import Flask, request, jsonify
import joblib
app = Flask(__name__)
model = joblib.load('model.pkl')
@app.route('/predict', methods=['POST'])
def predict():
data = request.get_json()
features = preprocess(data['features'])
prediction = model.predict([features])
return jsonify({'prediction': prediction.tolist()})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
2.2 高性能服务框架
Flask/FastAPI:轻量级,适合小规模部署和小型团队
TensorFlow Serving:专为 TF 模型设计的服务框架,支持模型版本管理、请求批处理
TorchServe:PyTorch 的官方模型服务框架
NVIDIA Triton Inference Server:支持多框架、动态批处理、GPU 加速
BentoML:从模型到部署的端到端框架
2.3 服务化架构模式
单体服务:一个服务处理所有请求
- 优点:架构简单,部署容易
- 缺点:扩展性差,耦合度高
微服务架构:将 ML 服务拆分为多个独立服务
- 特征服务:在线特征计算
- 模型服务:模型推理
- 路由服务:A/B 测试、流量分配
无服务器架构(Serverless):
- AWS Lambda / Google Cloud Functions
- 按需付费,自动扩缩容
- 适合推理频率不高的场景
2.4 性能优化
请求批处理(Batching):将多个请求合并为一批进行推理,充分利用 GPU 并行能力
模型量化(Quantization):将 FP32 权重转为 INT8,减少模型大小和推理延迟
模型剪枝(Pruning):移除不重要的网络连接
知识蒸馏(Knowledge Distillation):用大模型训练小模型
# TensorFlow 模型量化示例
import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model('model/')
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_model = converter.convert()
三、边缘部署
3.1 边缘计算场景
边缘部署是指将模型部署在靠近数据源的位置,而非云端。
适用场景:
- 低延迟需求:自动驾驶需要在毫秒级做出反应
- 离线场景:物联网设备在网络不稳定环境下运行
- 隐私要求:数据不能离开本地设备
- 带宽成本:传输大量数据到云端成本高
3.2 部署平台
移动端:
- TensorFlow Lite:在手机和嵌入式设备上运行
- Core ML(Apple):iOS 设备上的 ML 框架
- PyTorch Mobile:PyTorch 的移动端方案
浏览器端:
- TensorFlow.js:在浏览器中运行模型
- ONNX Runtime Web:浏览器端的 ONNX 推理
嵌入式设备:
- NVIDIA Jetson:边缘 AI 计算平台
- Raspberry Pi:低成本边缘设备
- Arduino / ESP32:微控制器级的 ML(TinyML)
3.3 边缘部署的挑战
- 资源限制:计算能力、内存、存储都有严格约束
- 模型大小:大模型无法部署在边缘设备上
- 功耗限制:电池供电设备需要低功耗
- 网络连接:更新模型时可能没有稳定的网络
- 设备碎片化:不同类型的设备需要不同的优化
# TensorFlow Lite 边缘部署
import tflite_runtime.interpreter as tflite
interpreter = tflite.Interpreter(model_path="model.tflite")
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
interpreter.set_tensor(input_details[0]['index'], input_data)
interpreter.invoke()
output_data = interpreter.get_tensor(output_details[0]['index'])
四、A/B 测试与渐进式发布
4.1 A/B 测试
部署新模型时,不应立即将所有流量切换到新模型。A/B 测试将流量分成两组:
- 对照组 A:使用当前生产模型
- 实验组 B:使用新模型
比较两组的关键业务指标,确保新模型确实改善后全量发布。
4.2 发布策略
蓝绿部署:维护两套完整环境,通过切换路由器一次性完成切换
灰度发布:逐步增加新模型的流量比例(5% → 25% → 50% → 100%)
金丝雀发布:先让一小部分用户使用新模型,监控无异常后逐步扩大
import random
def predict_with_canary(features, new_model, old_model, canary_rate=0.05):
if random.random() < canary_rate:
return new_model.predict(features)
return old_model.predict(features)
五、总结
- 模型序列化将训练好的模型保存为可部署的格式
- API 服务将模型封装为可通过 HTTP 调用的服务
- 性能优化包括批处理、量化、剪枝等技术
- 边缘部署将模型部署在移动端、浏览器、嵌入式设备
- 渐进式发布通过 A/B 测试和灰度发布降低部署风险
六、部署模式与架构
6.1 实时推理 vs 批量推理
实时推理(Online Inference):
- 请求-响应模式,毫秒级延迟
- 适用于推荐、风控等需要实时响应的场景
- 需要持续运行的服务和负载均衡
- 关注 P99 延迟和吞吐量
批量推理(Batch Inference):
- 定期运行(如每天凌晨),处理大量数据
- 适用于用户画像、营销名单生成等场景
- 可以使用 Spark 等分布式计算框架
- 关注吞吐量和成本效率
流推理(Streaming Inference):
- 每条数据到达时立即处理
- 适用于超低延迟、高吞吐量场景
- 使用 Kafka Streams、Flink 等流处理引擎
6.2 缓存策略
在实时推理中,缓存策略可以显著降低延迟和计算成本:
结果缓存:对相同的输入直接返回缓存结果
- TTL 控制缓存过期时间
- LRU 淘汰策略管理缓存大小
特征缓存:缓存特征计算的结果
- 用户特征、物品特征等变化不频繁的特征
- Redis 或 Memcached 作为缓存层
6.3 模型热加载
在不中断服务的情况下更新模型:
- 使用模型版本号管理
- 信号通知服务重新加载模型
- 健康检查确保新模型加载成功
import signal
import threading
class ModelServer:
def __init__(self):
self.model = self.load_model('v1')
self.lock = threading.Lock()
def load_model(self, version):
# 加载指定版本的模型
pass
def reload_model(self, version):
new_model = self.load_model(version)
with self.lock:
self.model = new_model
print(f"Model upgraded to {version}")
@app.route('/predict', methods=['POST'])
def predict():
with self.lock:
result = self.model.predict(features)
return jsonify({'prediction': result})
6.4 部署自动化
基础设施即代码(IaC)使得部署过程可重复、可审计:
- Docker:定义运行时环境
- Kubernetes:编排容器、自动扩缩容、滚动更新
- Helm:Kubernetes 应用的包管理
- Terraform:管理云基础设施(VM、网络、存储)
AB 测试与模型灰度发布
模型上线最关键的原则是——永远不要一次性将新模型部署到全部流量。正确的做法是进行灰度发布:先让新模型处理 1% 的流量,观察一段时间(通常至少 24 小时)确认没有异常后,逐步提升流量比例。灰度发布可以大幅降低模型线上事故的风险。
AB 测试框架是评估模型在线效果的黄金标准。在 AB 测试中,用户被随机分为对照组(使用旧模型)和实验组(使用新模型),通过比较两组的业务指标来决定新模型是否胜出。AB 测试的关键在于:足够的样本量(通过统计功效分析确定实验周期)、合理的分流策略(保证对照组和实验组在统计上等价)、以及适当的评估指标(同时关注主要指标和护栏指标)。
延伸阅读
- 📺 B 站播放列表:MLOps Production — 机器学习工程生产实践
- 📚 更多学习资源,请访问 deeplearning.ai 官网