Open egolearner opened 5 years ago
http://proceedings.mlr.press/v67/li17a.html
Uber使用机器学习的场景有预测供求、餐厅推荐、地图和自动驾驶等。 Uber机器学习的挑战
解决思路
Uber使用SQL作为各种数据源的查询接口,查询引擎底层进行优化。数据源都有metadata,不同的用例可以共享数据准备任务。
Batch和实时机器学习流水线共享特征计算引擎和Feature Store。只需要在数据流水线中指定UUID,就可以通过特征名称获取特征。 在线预测可以低延时地从在线存储(Cassandra)中查询特征。批量训练、预测和在线预测使用统一的标准(canonical)名称来访问特征,在线和离线可以使用相同的表达式来获取特征。
将模型组织为分层结构,训练一个有层次的模型部署到所有城市。 支持将模型一键部署成批量预测或在线服务。
为保证批量和在线的模型结果相同,模型服务Core可以给批量预测流水线和在线预测容器使用。 在线请求中包括基础特征和Model ID,预测服务再从Feature Store补全特征,进行特征变换,然后调模型服务Core来做预测。 批量模型和实时模型,所有的预测结果都写入Kafka用于诊断和监控。
需求
特征计算的挑战 统一流批引擎的限制
特征Serving的挑战 批量训练和在线预测的特征分开存储,原因是
Uber选择流批计算分别选用Samza, Spark作为计算引擎,特征存储分别选用Hive, Cassandra作为离线和在线的特征存储。 引擎分开后,需要保证以下三点:
Feature Group是调度和存储的基本单元,同一group的特征由同一job计算,存储到同一表中。 Feature owner来定义特征组和向已有特征组来添加特征。 每个Feature Group都有meta YAML文件,定义语义和一组源码文件。使用git管理,可以做CR和批准。 废弃特征需要通知到用户,平台会记录使用信息。 活跃特征的语义不允许变更,变更语义时需要产生新特征。
Spark ETL任务来生成一组相关特征(Feature Group),结果写入Hive表中,每列一个特征。每行由唯一ID和分区时间作为Key。 ETL任务完成后,也需要拷贝到在线特征存储中。
在线存储有两个源:历史特征和从Kafka topic计算得到的实时特征。 特征补全之后,使用DSL做特征变换。
之前的方案是每个城市训练一个模型,管理上百个模型既耗时又容易出错。
使用分层次的分区模型,作为一个逻辑模型来训练和管理。如果某一分区的数据不足以训练模型,自动回退到父模型或祖先模型。 在持久化全局训练和验证集时带有每个分区的metadata,在创建分区训练和验证集时不需要再序列化和存储数据。持久化数据也可以用于fail over和re-train。 使用Spark自顶向下训练,每一层并行训练。一个分层次模型使用一个Spark任务来训练(既非依赖工作流调度器,也非依赖外部的控制器)。
使用TChannel作为网络协议。 在请求Header中指定使用的模型,预测服务检查header路由到指定的模型。 预测结果写入Kafka,join实际结果,然后发布监控和报警指标。 使用API来上下线模型。上线前会打包必要的文件,验证模型可以正确运行,然后部署到容器。
https://www.youtube.com/watch?v=MpnszJ_3Ong https://eng.uber.com/michelangelo/ https://eng.uber.com/scaling-michelangelo/
http://proceedings.mlr.press/v67/li17a.html
1 概述
Uber使用机器学习的场景有预测供求、餐厅推荐、地图和自动驾驶等。 Uber机器学习的挑战
解决思路
2 系统架构总览
2.1 数据准备
Uber使用SQL作为各种数据源的查询接口,查询引擎底层进行优化。数据源都有metadata,不同的用例可以共享数据准备任务。
2.2 Feature Store
Batch和实时机器学习流水线共享特征计算引擎和Feature Store。只需要在数据流水线中指定UUID,就可以通过特征名称获取特征。 在线预测可以低延时地从在线存储(Cassandra)中查询特征。批量训练、预测和在线预测使用统一的标准(canonical)名称来访问特征,在线和离线可以使用相同的表达式来获取特征。
2.3 Model Training
2.4 模型部署和管理
将模型组织为分层结构,训练一个有层次的模型部署到所有城市。 支持将模型一键部署成批量预测或在线服务。
2.5 模型服务和实时监控
为保证批量和在线的模型结果相同,模型服务Core可以给批量预测流水线和在线预测容器使用。 在线请求中包括基础特征和Model ID,预测服务再从Feature Store补全特征,进行特征变换,然后调模型服务Core来做预测。 批量模型和实时模型,所有的预测结果都写入Kafka用于诊断和监控。
3 特征计算和服务
3.1 需求与挑战
需求
特征计算的挑战 统一流批引擎的限制
特征Serving的挑战 批量训练和在线预测的特征分开存储,原因是
3.2 解决方案
Uber选择流批计算分别选用Samza, Spark作为计算引擎,特征存储分别选用Hive, Cassandra作为离线和在线的特征存储。 引擎分开后,需要保证以下三点:
3.2.1 Feature Groups
Feature Group是调度和存储的基本单元,同一group的特征由同一job计算,存储到同一表中。 Feature owner来定义特征组和向已有特征组来添加特征。 每个Feature Group都有meta YAML文件,定义语义和一组源码文件。使用git管理,可以做CR和批准。 废弃特征需要通知到用户,平台会记录使用信息。 活跃特征的语义不允许变更,变更语义时需要产生新特征。
3.2.2 批量计算和存储
Spark ETL任务来生成一组相关特征(Feature Group),结果写入Hive表中,每列一个特征。每行由唯一ID和分区时间作为Key。 ETL任务完成后,也需要拷贝到在线特征存储中。
3.2.3 近实时特征计算和在线存储
在线存储有两个源:历史特征和从Kafka topic计算得到的实时特征。 特征补全之后,使用DSL做特征变换。
4 分区模型
4.1 挑战
之前的方案是每个城市训练一个模型,管理上百个模型既耗时又容易出错。
4.2 解决方案
使用分层次的分区模型,作为一个逻辑模型来训练和管理。如果某一分区的数据不足以训练模型,自动回退到父模型或祖先模型。 在持久化全局训练和验证集时带有每个分区的metadata,在创建分区训练和验证集时不需要再序列化和存储数据。持久化数据也可以用于fail over和re-train。 使用Spark自顶向下训练,每一层并行训练。一个分层次模型使用一个Spark任务来训练(既非依赖工作流调度器,也非依赖外部的控制器)。
5 实时预测和监控
使用TChannel作为网络协议。 在请求Header中指定使用的模型,预测服务检查header路由到指定的模型。 预测结果写入Kafka,join实际结果,然后发布监控和报警指标。 使用API来上下线模型。上线前会打包必要的文件,验证模型可以正确运行,然后部署到容器。
6 经验教训