You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

150 lines
15 KiB
Markdown

2 years ago
# 18 | 分布式计算模式之流水线:你方唱罢我登场
你好,我是聂鹏程。今天,我来继续带你打卡分布式核心技术。
通过前面几篇文章我们一起学习了分布式计算模式中的MapReduce、Stream和Actor它们各显神通解决了很多实际问题。
但是,在现实生活中,经常还会出现这样的情况,前一个任务的结果是另外一个任务的输入。比如工厂生产一瓶饮料,首先需要往瓶子里装上饮料,待饮料装满后,再封口。如果装饮料和封口分别为子任务,那么前一个任务(装饮料)结束后才可以开始第二个任务(封口)。类似这样的作业,就是我们常说的流水线作业。
在分布式领域中解决类似具有依赖关系的流水线作业的计算模式,叫作流水线计算模式。其实,流水线计算模式是我们在[第1篇文章](https://time.geekbang.org/column/article/140004)中提到的数据并行计算的一种形式,就是将一个任务拆分为多个步骤(子任务),然后多个这样的任务通过对步骤(子任务)的重叠执行,以实现数据并行处理的场景。
这种流水线模式在计算机领域中最先用于CPU指令设计后来推广到机器学习领域进行数据处理、模型训练等。在流水线计算模式中由于前一个子任务执行后会扔给下一个子任务由下一个子任务去展现自己的能力因此可以形象地比喻为“你方唱罢我登场”。
接下来,我们就一起打卡分布式计算模式中的流水线模式吧。
## 什么是流水线模式?
其实,分布式领域的流水线计算模式,就是参考了工业生产中的流水作业模式,将一个任务分为多个步骤执行,使得不同任务可以并行执行。此外,你肯定还会想到计算机技术中的流水线计算吧。
计算机中的**流水线Pipeline**技术是一种将每条指令拆分为多个步骤多条指令的不同步骤重叠操作从而实现几条指令并行处理的技术。现代CPU指令采用了流水线设计将一条CPU指令分为取指IF、译码ID、执行EX、访存MEM、回写WB五级流水线来执行。
如下图所示,在第一条指令执行译码操作时,第二条指令就可以执行取指操作了,从而实现了多条指令的并行操作。
![](https://static001.geekbang.org/resource/image/75/08/75c9e4c34848d1d6e9bfc77705d7d108.png)
在分布式领域中,**流水线计算模式**也类似,它是将一个大任务拆分为多个步骤执行,不同的步骤可以采用不同的进程执行。这,使得不同任务可以并行执行,从而提高了系统效率。
以机器学习中的数据预处理为例假设现在有5个样本数据每个样本数据进行数据预处理的流程包括数据去重、数据缺失值处理、数据归一化3个步骤且需要按照顺序执行。也就是说数据预处理这个任务可拆分为数据去重—>数据缺失值处理—>数据归一化3个子任务。
如果现在有3个节点节点1执行数据去重节点2执行数据缺失值处理节点3执行数据归一化。那么节点1处理完样本1的数据将处理后的数据发送节点2后则节点1可以继续处理样本2的数据同时节点2处理样本1的数据以此类推就实现了多任务的并行执行。
接下来,我们再具体看看分布式领域中的流水线计算模式吧。
## 流水线计算模式
流水线计算模式的应用非常广泛在AI技术中也非常常见。对流水线计算模式的学习将有助于你学习AI技术因此我接下来会以机器学习为例为你介绍流水线计算模式。
当然流水线计算模式的原理是通用的也可以应用到其他领域比如通信领域中使用HTTP流水线传输、计算机图形学中的图流水线等。
随着神经网络、深度学习在全世界掀起了All in AI的热潮用于加速的GPU和TPU也被越来越多的人使用。虽然诸如GPU、TPU之类的加速器可以从根本上减少执行单个训练步骤所需的时间但**为了达到最佳性能,我们仍然需要高效的输入流水线机制。**
比如在流水线模式中数据预处理与GPU/TPU进行模型训练可以重叠进行再比如第N个样本进行模型训练时第N+1个样本可以进行数据预处理也就是说在第N+1个样本进行预处理前已经将第N个样本处理后的数据提供给了模型训练进一步减少了整体的数据处理和模型训练时间。
Tensorflow是Google开源的一个分布式机器学习框架已被各大公司采用比如网易、eBay、Intel等公司。接下来我就以TensorFlow的输入流水线模式为例与你介绍流水线技术模式的原理并带你了解如何构建机器学习的流水线。
### 流水线计算模式的原理
TensorFlow运用了流水线模式对输入数据进行预处理因此称为输入流水线TensorFlow Training Input Pipelines。其数据输入流水线主要包含3个步骤
* **提取Extract**。通过多种途径读取数据比如内存、本地的HDD或SSD、远程的HDFS、GCS等。数据的种类也有很多比如图像数据、文本数据、视频数据等。
* **转换Transform**。使用 CPU处理器对输入的数据进行解析以及预处理操作包括混合重排shuffling、批处理batching, 以及一些特定的转换。比如图像解压缩和扩充、文本矢量化、视频时序采样等。
* **加载Load**。将转换后的数据加载到执行机器学习模型的加速器设备上比如GPU 或 TPU。
由于输入流水线包含了提取、转换、加载3个步骤因此**TensorFlow的数据输入流水线也称为ETL流水线**。TensorFlow提供了一个官方API也就是tf.data利用简单、可重用的数据片段构建复杂的输入流水线。
没错在加速模型训练方面输入流水线是非常重要的一个模块。由上述流程可知要执行训练步骤首先需要提取并使用CPU转换数据然后将其提供给在加速器上运行的模型。
如果不引入流水线模型的话,当 CPU 正在预处理数据时加速器处于空闲状态。同样当GPU/TPU正在训练模型时CPU 处于空闲状态。因此,训练的用时是 CPU 预处理时间和加速器训练时间的总和。
为了帮助你理解,**我们一起看下**[**TensorFlow官网**](https://www.tensorflow.org/guide/data_performance)**给出的一个示例吧**。这个例子展示了一个不使用流水线技术和使用流水线技术时CPU、GPU/TPU的训练过程对比。
我们先看看不使用流水线技术的训练过程。如下图所示Prepare 1表示CPU正在对第1个样本数据进行预处理操作Train 1表示GPU/TPU正在训练第1个样本数据。
![](https://static001.geekbang.org/resource/image/5a/f2/5ad2604aac06d7ed8448e0b0b7dfd0f2.png)
备注:图片来源为[www.tensorflow.org/guide](http://www.tensorflow.org/guide)。
图中的“idle”指的是空闲时间。可以看出如果不使用流水线CPU 和 GPU/TPU 运作的时间没有重叠,因此在大部分时间都可能处于空闲状态。
接下来我们再看看使用流水线技术的训练过程。流水线模型可以将训练步骤的数据预处理和数据训练过程重叠到一起。比如当GPU/TPU正在训练第 N 个样本数据时CPU 可以预处理第 N+1 个样本数据。这样做不仅可以最大限度地缩短训练的单步用时,还可以缩短提取和转换数据所需的时间,如下图所示:
![](https://static001.geekbang.org/resource/image/bf/b9/bf19b31ba9dd27cb7b1a6e63019476b9.png)
图片来源:[www.tensorflow.org/guide](http://www.tensorflow.org/guide)
很明显采用流水线的设计可以充分利用CPU和GPU/TPU从而避免资源闲置加速训练过程。
**到这里,我们来小结一下吧。**
TensorFlow的输入流水线模式将对数据的操作拆分为提取、转换、加载3个不重叠的部分。当CPU对第N个样本的数据完成预处理之后会将预处理后的数据发送给GPU/TPU然后CPU继续对第N+1个样本的数据进行预处理同时GPU/TPU对第N个样本数据进行模型训练。也就是说这种计算模式实现了多样本数据处理和模型训练的并行执行。
可以看出,在模型训练中引入流水线模式,可以提高 CPU、GPU/TPU的利用率还可以加速训练过程。
### 实践: 构建机器学习流水线
前面提到在TensorFlow中流水线模式主要运用在数据读取阶段。那么对于一个复杂的机器学习任务是否也可以构建一套流水线作业呢
答案是肯定的。接下来,我们就一起看看,如何构建机器学习流水线。
一个典型的机器学习训练模型按照流水线计算模式拆分可以包括如下所示的5个步骤
1. **数据输入**,指的是从不同的数据源中导入数据。
2. **数据转换**,主要是要把输入的无结构数据转换成合适的格式,以便特征提取。
3. **特征提取**,指的是从数据集中提取特征数据。
4. **模型训练**,包括提供一个算法,并提供一些训练数据让模型可以学习。学习算法会从训练数据中发现模型,并生成输出模型。
5. **模型验证**,指的是通过训练得到的结果,对模型进行错误率验证。比如,图像分类中分类结果的验证,预测中的准确度验证,从而提高模型的准确性。
![](https://static001.geekbang.org/resource/image/9d/21/9de5f259c32b8f3f3cae6edaf5527821.png)
值得注意的是,在数据输入和数据转换之间,有时需要进行数据清洗。数据清洗主要是剔除错误数据和不重要的数据,从而降低模型训练的错误率。
接下来,**我以图像分类为例,带你了解机器学习流水线的流程。**关于图像分类的详细知识点,你可以自行查阅相关资料。
如下图所示假如现在有10000张小狗照片需要训练出一个关于小狗的预测模型。
![](https://static001.geekbang.org/resource/image/4a/d3/4a0022453c24ec07309cf49475919ed3.png)
假设这10000张照片中8000张作为训练集2000张作为测试集采用CNN进行模型训练。CNN包括输入层、卷积层、池化层、全连接层其中输入层为数据输入卷积层和池化层为特征提取全连接层是连接所有特征输出数据到分类器中以得到训练结果。
如上图所示生成小狗预测模型的流水线可以分为数据输入、数据转换、特征提取、模型训练、模型验证5部分。具体流程如下
1. 输入数据也就是输入图像数据即8000张图片其中图像以像素表示。比如图片的大小是480_480那么图像输入数据格式可以是480_480\*3的数组。3代表的是RGB的维度。
2. 数据转换,也就是对输入的图像数据进行解析、正则化处理,消除一些噪声数据,得到格式化的数据。
3. 特征提取,指的是得到格式化的数据之后,就可以对输入图像进行特征提取,通过卷积操作提取小狗的一些轮廓特征,比如耳朵、尾巴、身体等,然后通过池化层识别出主要特征,比如小狗的耳朵、眼睛、舌头等,对特征进行精简。
4. 模型训练。在CNN中模型训练其实和特征提取是相辅相成的也就是特征提取后实现特征提取的那些参数就是模型参数而训练过程会根据梯度下降法等对参数进行调整以使得在模型验证阶段预测结果逼近真实结果。也就是说特征提取和模型训练这两步在CNN中是放到一起的这里我为了方便你理解才显式地把这两步划分了出来。
5. 模型验证。将带有标签的测试数据集的图像2000张输入到小狗预测模型将预测结果与实际结果进行对比如果误差比较大则对模型参数进行优化并进入下一次迭代训练如果误差较小那么得到的结果就是最终的小狗预测模型。
## 知识扩展流水线模式和MapReduce模式中都有将大任务拆分为多个子任务两者的区别是什么
如题目所述流水线计算模式与分而治之的MapReduce计算模式你可以再回顾下[第15篇文章](https://time.geekbang.org/column/article/155575)中的相关知识点)有相似之处,都是将一个完整的、大的任务进行划分,但它们**划分的模式**不一样:
* MapReduce以任务为粒度将大的任务划分成多个小任务每个任务都需要执行完整的、相同的步骤同一任务能被并行执行可以说是任务并行的一种计算模式
* 而流水线计算模式以步骤为粒度,一个任务拆分为多个步骤,每个步骤执行的是不同的逻辑,多个同类型任务通过步骤重叠以实现不同任务的并行计算,可说是数据并行的一种模式。
此外,它们的子任务(步骤)间的关系不同:
* 在MapReduce中各个子任务可以独立执行互不干扰多个子任务执行完后进行结果合并得到整个任务的结果因此要求子任务之间是没有依赖关系的
* 而在流水线模式中,多个子任务之间是具有依赖关系的,前一个子任务的输出是后一个子任务的输入。
所以综合来讲MapReduce计算模式适合任务并行的场景而流水线计算模式适合同类型任务数据并行处理的场景。
## 总结
首先,我与你介绍了什么是分布式计算模式中的流水线模式。它参考了工业生产中的流水作业模式,将一个任务分为多个步骤执行,不同任务之间的步骤可以重叠执行,这使得多个不同任务可以并行执行。
然后,我以典型的机器学习流程为例,介绍了机器学习流水线处理流程,以加深你对分布式流水线计算模型的理解。
最后我以CNN进行小狗分类模型训练为例通过讲述数据输入、数据处理、特征提取卷积、池化等操作、模型训练、模型验证等过程带你进一步理解了流水线计算模式在实际应用中的原理。
现在,我再通过一张思维导图来归纳一下今天的核心知识点吧。
![](https://static001.geekbang.org/resource/image/43/5e/4329251192d6d77935e0de98ff8ebf5e.png)
流水线计算模式适合同类型任务,且每个任务可以拆分为多个步骤(子任务)进行执行的场景,通过重叠执行多个不同任务间的不同步骤实现数据并行。在实际应用场景中,有很多例子,最常见的就是机器学习。相信你在理解了本文的计算原理之后,一定可以将这种研究方法运用在你的工作中,加油!
## 思考题
流水线计算模式和流计算的区别是什么?
我是聂鹏程,感谢你的收听,欢迎你在评论区给我留言分享你的观点,也欢迎你把这篇文章分享给更多的朋友一起阅读。我们下期再会!