From 083cb5fc5e895e928a7817faa736706b911861dc Mon Sep 17 00:00:00 2001 From: Tongxuan Liu Date: Sun, 24 Apr 2022 12:42:49 +0800 Subject: [PATCH] [Docs] Refine user document of Multi-Hash Variable, Processor, Executor-Optimization. (#175) --- docs/Executor-Optimization.md | 7 ++++--- docs/Multi-Hash-Variable.md | 4 ++-- docs/Processor.md | 23 ++++++++++++++--------- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/docs/Executor-Optimization.md b/docs/Executor-Optimization.md index 73aeabf0ff8..6de390667cb 100644 --- a/docs/Executor-Optimization.md +++ b/docs/Executor-Optimization.md @@ -1,12 +1,13 @@ # Executor优化 ## 功能介绍 Runtime在调度上,做了相应的优化,目前主要优化CPU端执行效率,后续会继续推出GPU runtime优化。 + ## 用户接口 -目前支持几种Executor策略,分别是 +目前支持三种Executor策略 #### 原生tensorflow executor -是默认executor,无需开关控制。 +默认executor策略。 #### Inline executor @@ -26,7 +27,7 @@ with tf.train.MonitoredTrainingSession( #### 基于CostModel的Executor -通过动态Trace指定的Session Run情况,统计与计算多组指标,通过CostModel计算出一个较优的调度策略。 +通过动态Trace指定的Session Run情况,统计与计算多组指标,通过CostModel计算出一个较优的调度策略。该功能中包含了基于关键路径的调度策略和根据CostModel批量执行耗时短的算子的调度策略。 **使用方式** 首先用户可以指定Trace哪些Step的Sesison Run来收集执行指标,默认是收集100~200 Step的指标,通过设置下列环境变量,用户可以自定义此参数。 diff --git a/docs/Multi-Hash-Variable.md b/docs/Multi-Hash-Variable.md index eb965049127..9b4f4215832 100644 --- a/docs/Multi-Hash-Variable.md +++ b/docs/Multi-Hash-Variable.md @@ -1,9 +1,9 @@ # Multi-Hash Variable ## 背景 -在深度学习场景中,为了训练ID类的特征(例如user id或者item id),通常是将id类的稀疏特征映射到对应的低维稠密embedding向量中。在推荐场景中,随着数据量的逐渐增大,为每一个id类特征都存储一个对应的embedding向量是不现实的(例如商品数量的会达到10亿,embedding vector的维度是16,用float存储,存储量会达到64G)。因此在推荐场景中广泛使用基于Hash的方法,即对每个特征进行一次hash,然后再取获取对应的embedding,这样的方法的确可以减少内存的使用,但是由于存在hash冲突,不同的特征会被映射到同一个embedding向量,进而影响训练效果。 +在深度学习场景中,为了训练ID类的特征(例如user id或者item id),通常是将id类的稀疏特征映射到对应的低维稠密embedding向量中。在推荐场景中,随着数据量的逐渐增大,为每一个id类特征都存储一个对应的embedding向量,即无冲突Hash方案(EmbeddingVariable)会导致模型通常要比有冲突Hash方法下的模型大(Variable)。为了解决更大的模型带来的Training/Inference性能和资源的开销,DeepRec中已提供了若干功能来解决性能和资源问题,1)特征淘汰,通过将过期特征淘汰清理,避免过期特征积累过多,浪费内存;2)特征准入,低频特征准入机制,避免低频特征过拟合的同时,降低内存占用;3)混合多级EmbeddingVariable,通过将冷门特征存储在廉价更大的存储介质来支持更大的模型;4)DynamicDimensionEmbeddingVariable,通过使用策略让冷门特征使用更小的dim来表达,来降低冷门特征对存储空间的占用。本文中介绍的Multi-Hash Variable功能是另一种降低内存/显存占用的方法。 ​ -《Compositional Embeddings Using Complementary Partitions for Memory-Efficent Recommendation Systems》paper中提出了一种新的思路,在解决Embedding使用内存量大的问题同时还可以为每个特征分配一个单独的embedding vector,具体方法是: +《Compositional Embeddings Using Complementary Partitions for Memory-Efficent Recommendation Systems》paper中提出了一种新的思路来降低内存占用的方法,具体方法是: 1. 构造若干个小的Embedding table 2. 每个对应的table对应一个hash function, 这些hash function需要互补,即对于每一个id,他对应的hash值集合是唯一的,与其他任何一个id都不完全相同。例如当有两个embedding table的时候,使用Quotient-Reminder可以保证每个key都有唯一的hash集合,具体如下图: diff --git a/docs/Processor.md b/docs/Processor.md index 9ea3618dfab..0d800d78622 100644 --- a/docs/Processor.md +++ b/docs/Processor.md @@ -1,4 +1,6 @@ -# 1.介绍 +# Processor + +## 介绍 DeepRec Serving Processor是用于线上高性能服务的Library,它以DeepRec为基石,实现多种实用功能: ● 支持自动发现并导入全量模型; @@ -18,9 +20,10 @@ DeepRec Serving Processor是用于线上高性能服务的Library,它以DeepRe ● 简易的API接口,让用户对接更方便。 Processor的产出是一个独立的so,用户可以很方便的对接到自己的Serving RPC框架中。 -# 2.编译 + +## 编译 编译详见[https://github.com/alibaba/DeepRec](https://github.com/alibaba/DeepRec)项目首页“**How to Build serving library**”部分,编译的产出是“**libserving_processor.so**”。 -# 3.使用 +## 使用 用户有两种使用方式: 第一,在用户框架代码中直接[dlopen](https://linux.die.net/man/3/dlopen)从而加载so中的符号。 @@ -28,7 +31,8 @@ Processor的产出是一个独立的so,用户可以很方便的对接到自己 第二,可以结合头文件“**serving/processor/serving/processor.h**”使用,头文件中将Processor相关的API暴露了,通过头文件和“**libserving_processor.so**”来调用serving API也比较方便。 **需要注意**:如果不是使用DeepRec docker,那么可能需要一些额外的so依赖,包括:libiomp5.so,libmklml_intel.so,libstdc++.so.6,用户可以[直接下载](http://tfsmoke1.cn-hangzhou.oss.aliyun-inc.com/deeprec/serving_processor_so.tar.gz),然后在执行时候Preload这些so。 -## API接口 + +#### API接口 Processor提供以下几组C API接口,用户在自己的Serving框架中需要调用下列接口。 **1) initialize** @@ -117,7 +121,7 @@ int output_size = 0; int state = get_serving_model_info(model, &output_data, &output_size); ``` -## 数据格式 +#### 数据格式 Processor需要的Request,Response等数据格式如下所示,这里我们使用Protobuf作为数据存储格式。同DeepRec下“**serving/processor/serving/predict.proto**”一致。 Protobuf是Protocol Buffers的简称,它是一种数据描述语言,用于描述一种轻便高效的结构化数据存储格式。 Protobuf可以用于结构化数据串行化,或者说序列化。简单来说,在不同的语言之间,数据可以相互解析。Java的protobuf数据被序列化之后在c++中可以原样解析出来,这样方便支持各种场景下的数据互通。 用户在客户端需要将数据封装成下面格式,或者在Process之前转成此格式。 @@ -280,7 +284,7 @@ message ServingModelInfo { **对于 PredictResponse**: map outputs:是map结构,key是 PredictRequest中output_filter中指定的names,value是返回的tensor。 -## 配置文件 +#### 配置文件 上面提到,在初始化时候需要调用函数: ```c void* initialize(const char* model_entry, const char* model_config, int* state); @@ -368,7 +372,7 @@ void* initialize(const char* model_entry, const char* model_config, int* state); "timeline_path": "oss://mybucket/timeline/" } ``` -## 模型路径配置 +#### 模型路径配置 在Processor中,用户需要提供checkpoint以及saved_model,processor从saved_model中读取meta graph 信息,包括signature,input,output等信息。模型参数需要从checkpoint中读取,原因是现在的增量更新依赖checkpoint,而不是saved model。在serving过程中,当checkpoint更新了,processor在指定的模型目录下发现有新的版本的模型,会自动加载最新的模型。saved model一般不会更新,除非graph变化,当真的变化了,需要重启新的processor instance。 用户提供文件如下: @@ -395,8 +399,9 @@ saved_model: | _ _ variables ``` 以上述为例,在配置文件中"checkpoint_dir"设置为“/a/b/c/checkpoint_parent_dir/”,"savedmodel_dir"设置为“/a/b/c/saved_model/” -# 4.示例 +## 示例 End2End的示例详见:serving/processor/tests/end2end/README 这里提供了一个完整的端到端的示例。 -# 5.Timeline收集 + +## Timeline收集 通过在config中配置timeline相关参数,能够获取对应的timeline文件,这些文件是二进制格式,不能直接在`chrome://tracing`中进行展示,用户需要在编译DeepRec完成后目录(一般是/root/.cache/bazel/_bazel_root/)下find这个config_pb2.py文件,并放在serving/tools/timeline目录下,在此目录下执行生成`chrome://tracing`能展示的timeline。