Skip to content

Latest commit

 

History

History
276 lines (181 loc) · 8.25 KB

工程化.md

File metadata and controls

276 lines (181 loc) · 8.25 KB

工程化

研发环境

研发环境作用:

持久化数据

数据分析

特征预处理

模型训练

模型验证以及调优(调优是调速度和精度)

  • 精度调优:查找预测错误的样本,观察预测错误的样本与预测正确的样本,分析模型为什么对这类样本出错,调整策略

  • 速度调优:速度关注的推理速度,可以使用轻量型模型,可以通过模型压缩(剪枝,量化,OONX)

模型保存和上传

研发环境的配置:

因为模型训练在此环境下发生,因此它是所需算力最大的环境,需要有GPU进行算力支持

版本控制:

(所有)训练好的模型是需要保存的,

一般使用训练结束时的时间戳作为模型版本的标识,方便回溯。

测试环境

测试环境的作用:

用于测试模型加载服务的关键指标,保证模型的正常预测功能以及相关工程化措施

需要提供测试用例给测试工程师来测试评估模型是否满足需求,模型稳定性是否满足上线条件

测试环境的配置:

需要与生产环境配置保持一致,算力要求不高,不需要GPU进行算力支持

测试环境的申请:

  • 申请时说明测试环境用来做什么,需要什么样的配置,算力适当即可,一般不配备GPU

  • 申请完之后需要将模型部署在测试服务器上,并应当满足上下游服务需求的接口

生产环境

生产环境作用:

测试的服务满足上线指标要求之后,即可将代码和模型部署在生产环境中。供线上请求调用。

生产环境配置:

与测试环境相同,生产环境决定测试环境,需要使用多借点分布,保证高可用性。


服务日志

日志:

由服务器自动创建和维护的文件(需要在代码中嵌入日志相关的功能)

日志一般负责信息打印,异常查询,数据指标的统计

日志级别

打印的内容一般会按照功能分为不同的级别(可以自定义级别)

  • DEBUG:测试过程中,寻找Bug是打印的信息,不会在生产环境中出现
  • INFO:正常的输出信息,作为某些功能正常启用的提示
  • WARNING:警告信息,作为模型功能可能出现异常的警告
  • ERROR:错误信息,说明某些代码运行出现了错误,需要及时修正

日志切割:

按天将日志进行分割

日志存档:

日志会越来越多占用磁盘空间,服务器上一般只保留3天的日志信息,定期将多余的日志存档转义到专门的硬盘存储

日志实现工具:Logging:

Logging工具的使用:

import os
# 从logging的处理器中导入时间切片处理器
from logging.handlers import TimedRotatingFileHandler

# 定义日志的写入路径
log_root = "./"
log_path = log_root + "flask.log"
if not os.path.exists(log_root):
    os.mkdir(log_root)


# 日志处理器主要配置日志处理方式的相关参数
# filename: 日志存储路径+日志名称
# when: 按什么时间分割,D: 天,H:小时,M:分钟,S:秒
# interval: 时间的数量,比如3天或15分钟
# backupCount: 后台日志的数量,保存多少份时停止,防止磁盘溢出
# encoding: 日志内容编码
# delay: 是否立即生效
# utc: 是否按照原子钟世界标准时间,否则使用本地时间
handler = TimedRotatingFileHandler(
    filename=log_path,
    when="D",
    interval=1,
    backupCount=15,
    encoding="UTF-8",
    delay=False,
    utc=True,
)

# 过往日志后缀
# eg: flask.log.2020-12-08 
handler.suffix = "%Y-%m-%d"

规范日志样式实现:

import logging

# 定义日志输出格式
LOG_FORMAT = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
# 设置处理器格式
handler.setFormatter(LOG_FORMAT)

# 实例化一个日志对象,日志对象具有添加某个处理器的功能
logger = logging.getLogger(__name__)
# 添加处理器
logger.addHandler(handler)
# 设置日志打印级别,默认不打印低于INFO(包括)的日志
logger.setLevel(logging.INFO)
# 打印具体信息
# 实际生产中,将打印模型的输入输出等关键信息
logger.info('info message')

输出效果:

2020-12-15 17:56:34,868 - INFO - info message

样例:

logger.setLevel(logging.INFO)
logger.info('开始读取文件')
img = cv2.imread(...)
if img is None:
    logger.setLevel(logging.ERROR)
    logger.info('错误 图片读取失败')
elselogger.setLevel(logging.INFO)
    logger.info('图片读取完成')

A/B测试

什么是A/B测试?

  • 制作多个版本,同一时间让组成成分相同的房客群组随机访问这些版本,收集个群组的用户的体验数据和业务数据,最后分析评估出最好的版本,正式采用
  • 目的是为了验证新方法/新模型的上线效果

什么是分流?

  • 具体来讲,最简单A/B testing一般包括两种对比逻辑:
    • 从服务端分流的小流量整体对比实验:90%流量按照原有逻辑,10%的流量分给新的模型预测。
    • 从模型服务进行分流对比:因为小流量对比实验受到一些极端情况的影响,比如线上分类不均衡。模型在小流量上给出了接近统一的结果,为了监控和避免这种情况,需要在服务中再将10%的中模型预测成1的数据进行分流,成为实验组和对照组,这样我们就是真正在比较模型预测成1的价值。90%的流量称为旧算法组。

服务在线指标

在线服务指标

  • RT(requests time):
    • 整个模型服务响应时间,服务中模型预测的总体时间。
    • 算法的速度对RT有直接影响。
  • RT要求:
    • 一般情况下,对于算法服务的RT要求小于100ms。
  • Flask框架下常规模型的响应时间:
    • sklearn实现的LR(线性回归):<10ms
    • sklearn实现的GBDT(梯度提升树):<20ms
    • Pytorch实现的MLP(全连接感知机):<70ms
    • Tensorflow实现的MLP(全连接感知机):<90ms
    • Pytorch实现的目标检测:<100ms
    • Tensorflow实现的目标检测:<100ms

响应时间自测方法:

import time
import requests
url = "http://0.0.0.0:5005/v1/test/"
data = {
    "userId": 102079311,
    "birthday": "1995-04-29T00:00:00.000+0000",
    "appId": 20000,
    "channel": 1,
    "countryId": 182,
    "createTime": "2020-11-02T02:51:19.000+0000",
    "languageId": "20",
    "type": 6,
    "stoneVersion": "other",
    "platformType": 2,
    "screenSize": "720*1440",
    "deviceName": "TECNO-BB4k",
}
start = time.time()
res = requests.post(url, json=data)
end = time.time()
print(end - start)
print(res.text)
  • QPS:
    • 每秒处理请求次数,与APP日活和峰值时刻有关
  • QPS一般对应量级:
    • 日活30万左右,服务QPS>20
    • 日活100万左右,服务QPS>80
    • 日活1000万左右,服务QPS>500
    • 日活3亿左右,服务QPS>5000

代码版本管理

GitLab

企业内部使用的项目管理和代码托管平台

GitHub

是一个面向开源以及私有软件项目的托管平台

Code review

代码合并之前需要code review,让你的同事检测代码确无误

QA流程:

测试,需要提供给QA人员测试用例以及预计响应的输出

正式环境部署

正式环境的节点申请

  • 考虑业务端服务器的位置,因为算法服务是内嵌服务,所以需要在同一个region。
  • 为了保证RT和QPS的重要指标,机器情况一般与测试机相同(4C,8G)。
  • 线上环境部署使用“干净”的基础镜像,并使用git clone代码。

Docker部署

  • Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
  • 将运行环境打包成虚拟容器,使用DockerFile进行服务启动命名的编写。