配音

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 边缘部署的挑战

  1. 资源限制:计算能力、内存、存储都有严格约束
  2. 模型大小:大模型无法部署在边缘设备上
  3. 功耗限制:电池供电设备需要低功耗
  4. 网络连接:更新模型时可能没有稳定的网络
  5. 设备碎片化:不同类型的设备需要不同的优化
# 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 测试将流量分成两组:

比较两组的关键业务指标,确保新模型确实改善后全量发布。

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)

五、总结

  1. 模型序列化将训练好的模型保存为可部署的格式
  2. API 服务将模型封装为可通过 HTTP 调用的服务
  3. 性能优化包括批处理、量化、剪枝等技术
  4. 边缘部署将模型部署在移动端、浏览器、嵌入式设备
  5. 渐进式发布通过 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 测试的关键在于:足够的样本量(通过统计功效分析确定实验周期)、合理的分流策略(保证对照组和实验组在统计上等价)、以及适当的评估指标(同时关注主要指标和护栏指标)。

延伸阅读