|
| 1 | +# Embedding lookup异步化 |
| 2 | + |
| 3 | +## 背景 |
| 4 | + |
| 5 | +在分布式训练的场景下,随着稀疏模型越来越复杂,模型的输入特征也越来越多。这导致每步训练时worker节点需要在ps节点进行大量的Embedding lookup操作,该操作的在整个端到端的耗时也不断增长,成为模型训练速度的瓶颈,导致不能高效地利用计算资源。 |
| 6 | + |
| 7 | +DeepRec提供了Embedding lookup异步化的功能,该功能能够自动地将Embedding lookup部分子图划分出来,并实现与计算主图部分的异步执行,从而实现通信过程与计算过程的重叠,消除模型通信瓶颈对训练的影响,提高计算资源利用率。优化整张图的执行效率,提升训练性能。 |
| 8 | + |
| 9 | +由于Embedding lookup操作异步化后,worker端梯度更新部分与Embedding lookup部分位于两张图内,将导致worker端无法获得PS端最新的Embedding lookup结果,有可能影响训练收敛速度和模型效果。 |
| 10 | + |
| 11 | +## 功能说明 |
| 12 | + |
| 13 | +在用户的原图有io stage阶段的前提下,通过开启async embedding功能,实现Embedding子图的自动切分,并实现embedding lookup的异步化,从而提高训练性能。 |
| 14 | + |
| 15 | +**注意:** |
| 16 | + |
| 17 | +1. 该功能开启的前提条件是用户的原图中存在一个io stage阶段,该阶段应当在读取样本之后,embedding lookup之前。相关内容请参见[流水线-Stage](./Stage.md)一节。 |
| 18 | +2. 该功能与[自动流水线-SmartStage](./Smart-Stage.md)冲突,开启async embedding功能后将自动关闭SmartStage功能。 |
| 19 | + |
| 20 | +## 用户接口 |
| 21 | + |
| 22 | +目前,该功能实现了DeepRec中以下Embedding lookup函数接口的支持。 |
| 23 | + |
| 24 | +```python |
| 25 | +tf.contrib.feature_column.sequence_input_layer() |
| 26 | +tf.contrib.layers.safe_embedding_lookup_sparse() |
| 27 | +tf.contirb.layers.input_from_feature_columns() |
| 28 | +tf.contirb.layers.sequence_input_from_feature_columns() |
| 29 | +tf.feature_column.input_layer() |
| 30 | +tf.nn.embedding_lookup() |
| 31 | +tf.nn.embedding_lookup_sparse() |
| 32 | +tf.nn.safe_embedding_lookup_sparse() |
| 33 | +tf.nn.fused_embedding_lookup_sparse() |
| 34 | +tf.python.ops.embedding_ops.fused_safe_embedding_lookup_sparse() |
| 35 | +``` |
| 36 | + |
| 37 | +该功能在ConfigProto中定义了如下配置选项 |
| 38 | + |
| 39 | +```python |
| 40 | +sess_config = tf.ConfigProto() |
| 41 | +sess_config.graph_options.optimizer_options.do_async_embedding = True |
| 42 | +sess_config.graph_options.optimizer_options.async_embedding_threads_num = 4 |
| 43 | +sess_config.graph_options.optimizer_options.async_embedding_capacity = 4 |
| 44 | +``` |
| 45 | + |
| 46 | +其中: |
| 47 | + |
| 48 | +| 配置选项 | 含义 | 默认值 | |
| 49 | +| --------------------------- | ------------------------------------------------ | ---------------- | |
| 50 | +| do_async_embedding | Async Embedding开关 | False(关闭) | |
| 51 | +| async_embedding_threads_num | 异步化执行embedding lookup子图线程数 | 0 (需手动指定) | |
| 52 | +| async_embedding_capacity | 缓存异步化执行embedding lookup子图结果的最大个数 | 0 (需手动指定) | |
| 53 | + |
| 54 | +**注意事项** |
| 55 | + |
| 56 | +1. `async_embedding_threads_num` 并不是越大越好,只需要可以让计算主图部分不必等待embedding lookup子图的结果即可,数量更大会抢占模型训练的计算资源,同时也会占用更多的通信带宽。建议按下述公式设置,可以从1开始向上调整。 |
| 57 | + $$ |
| 58 | + async\_embedding\_threads\_num >= Embedding\ lookup\ 子图执行耗时 / 计算主图执行耗时 |
| 59 | + $$ |
| 60 | + |
| 61 | +2. `async_embedding_capacity` 更大会消耗更多的内存或缓存。同时也会造成缓存的embedding lookup子图结果与从PS端获取的最新结果有较大差异,造成训练收敛慢。建议设置为`async_embedding_threads_num` 的大小,可以从1开始向上调整。 |
| 62 | + |
| 63 | +## CPU集群性能对比 |
| 64 | + |
| 65 | +机型为Aliyun ECS实例 ecs.hfc7.24xlarge,10台组成训练集群。 |
| 66 | + |
| 67 | +集群配置如下表所示。 |
| 68 | + |
| 69 | +| 项目 | 说明 | |
| 70 | +| -------- | ---------------------------------------------------- | |
| 71 | +| CPU | Intel Xeon Platinum (Cooper Lake) 8369 96核心 | |
| 72 | +| MEM | 192 GiB | |
| 73 | +| 网络带宽 | 32 Gbps | |
| 74 | + |
| 75 | +训练配置 |
| 76 | + |
| 77 | +| 项目 | 说明 | |
| 78 | +| ------------- | ---- | |
| 79 | +| PS 数量 | 8 | |
| 80 | +| worker数量 | 30 | |
| 81 | +| PS 核心数 | 15 | |
| 82 | +| worker 核心数 | 10 | |
| 83 | + |
| 84 | +模型性能 |
| 85 | + |
| 86 | +| 模型 | baseline性能(global steps/sec) | async embedding功能性能(global steps/sec) | 加速比 | |
| 87 | +| ---- | -------------------------------- | ------------------------------------------- | ------ | |
| 88 | +| DLRM | 1008.6968 | 1197.932 | 1.1876 | |
| 89 | + |
0 commit comments