在此选用了业界主流的三种深度学习框架Paddle,TensorFlow和Mxnet,对它们分别作了实战评估。用于测试的模型包括基于logistic回归模型和LSTM模型。
作为当下最热门的话题之一,Google,Baidu、Facebook等巨头都围绕深度学习重点成立了一些研究中心。而这些公司正是最早的一批将机器学习技术广泛且充分应用于自身主营业务的公司,如今也一直在构建一些高效的深度学习框架。如Google的TensorFlow、Baidu的Paddle等。这些框架一旦被开源,很大一部分地解决了网络模型难以配置和实现的问题。大大降低了深度学习的门槛,给工业界广泛地应用深度学习技术带来了福音。
本文测试的深度学习框架主要包括百度的PaddlePaddle、Google的Tensorflow和DMLC的Mxnet。 深度学习框架专注于让研究或开发人员快速搭建训练极为耗时的复杂神经网络模型。而对于传统的机器学习算法,它们通常不需要很长的计算时间,模型结构也相对简单,开发难度相对较易,一般皆可在常用统计分析软件如Python、R中找到相应的扩展包。开源深度学习框架也可以看作是一种第三方“扩展包”。这个包向用户提供了神经网络的数据导入模块,模型网络结构配置模块和训练模块等(配置训练模块主要是定义合适的损失函数,选择合适的优化算法和参数来估计模型中的参数。训练模块选择的恰当有时可以达到事半功倍的效果)。与传统的机器学习扩展包不同,深度学习框架底层使用多种语言开发,如有C/C++、CUDA、Lua等。此外,框架可支持分布式训练包括数据分布式和模型分布式,还可利用多种计算资源如CPU、GPU、FPGA和Mobile等。这些都是为了充分高效地利用硬件资源以提高模型的训练速率。
三种深度学习框架总览
框架名称 | 主语言 | 从语言 | 适用平台 | 文档 | 上手难易 |
Paddle | C++/CUDA | Python | Linux/OSX | 较为全面 | 中 |
TensorFlow | C++/CUDA | Python | Linux/OSX | 全面 | 难 |
Mxnet | C++/CUDA | Python/R/ Julia/Go/ JavaScript/ Matlab | Linux/OSX/Windows/Android | 全面 | 难 |
本次测试的指标主要包括个框架的单机训练效率,分布式训练效率,模型配置的复杂度和灵活性。参与训练的模型分别为结构相对简单,训练耗时较短的Logistic回归模型和结构相对复杂、训练耗时较长的LSTM模型。LR(Logistic Regression的简称,下同)模型是构建的初期反欺诈模型,LSTM(长短期记忆神经网络模型)则是构建的风险事件识别模型。它们的具体网络结构如下图所示。
LR模型本身相当于一个单层的二分类“神经网络模型”。模型二则可看作由三个部分构成:第一个部分是Embedding层,其作用是将句子中出现的词从维度较高的one-hot向量映射为维度较低的词向量表示。第二个部分为主要的LSTM层,它将句子中出现的词的特征从前往后传递。第三个部分相当于一个多分类的LR层,是负责根据第二个部分提取出的特征进行分类识别。参与LR模型训练的数据大约有10万条左右的样本,样本宽度有1000多维,而参与LSTM模型训练的数据有50多万条样本,字典大小为8万多,模型结构较为复杂。因此,后者的训练时间会远远大于前者。在这两种模型下,可测出三种深度学习框架在应对两种反差较大情形时的性能表现情况。
在测试框架的单机和分布式性能时,采用控制变量的方法。保证使用的硬件、操作系统、应用软件、训练数据、模型结构以及模型参数完全相同。评估不同框架训练同一模型时的耗时情况。测试服务器为两台型号相同的浪潮NF5280M4(Intel(R) Xeon(R) CPU E5-2670 v3 @2.30GHz;48C/256G;千兆网卡),操作系统为Suse12,Docker版本为1.2,其中Paddle版本为0.9.0a0,TensorFlow版本为0.10.0,Mxnet版本为0.9.3。
测试一:Logistic回归模型
在锁定模型所有参数相同,迭代为30次时,不同框架在不同CPU核数下的单测试结果和在两台完全相同服务器下,8CPU环境的分布式测试结果如下图所示。
从测试结果来看,对于结构简单的LR模型,Paddle的表现显得有些笨重,训练时间远远多于其他两个框架,并且对CPU核数并不敏感,而分布式耗时要比单机还要高出5倍以上。Mxnet和TensorFlow的在单机环境下表现出的差异不大,前者有着微弱的优势。但在分布式环境下,Tensorflow的训练时间也高出了单机环境的2倍左右,Mxnet在分布式环境下的表现比较正常,即便是在秒速训练完成的简单模型下也会比单机时快上几秒。但它在8核CPU下的训练时间却有些反弹,而TensorFlow却可以充分的利用好CPU资源,随着核数增加,训练时间也会逐渐减少。
测试二:LSTM模型
同样锁定模型的所有参数相同,设训练次数为5次,则不同框架在不同CPU核数下的单测试结果和 在两台完全相同服务器下,8核CPU环境的分布式测试结果如下所示。
从测试结果来看,在单机情况下,Paddle的表现相对于其他两者有着明显的优势,几乎要快上一倍以上,但其对CPU核数的利用似乎还不是特别敏感,仅有略微提升。TensorFlow表现的相对较慢,不过它对CPU的利用依然高效,8核环境下要比2核环境下快上1.7倍左右。Mxnet表现的相对中庸,从4核下的表现来看,它比TensorFlow要快上1倍多,但Paddle又比它快1倍多,且与LR模型测试时情况一样,它在4核CPU下要比2核快上37%,但在8核下训练时间仍有反弹情况(这可能与编译安装Mxnet时,默认的环境变量参数有关)。在分布式情况下,Paddle表现的不是很理想,训练时间要比单机下慢上3.1倍。而TensorFlow和Mxnet要比单机训练时间分别快上21%和26%。 总体来讲,在单机情况下,Paddle的表现虽然有些极端,但它在复杂模型上的优势还是比较明显。但若是分布式环境,那么Mxnet似乎要比TensorFlow略胜一筹。
三种深度学习框架底层均由C/C++和CUDA开发,支持GPU运算。但对于建模人员来说最常用的是它们的外围语言Python,R等。模型的开发周期一般可分为数据预处理,模型配置,模型训练及调优,模型发布这四个部分。数据预处理部分属于框架外围,不同框架的处理方式和复杂度基本无差异。关键在于模型配置这部分。这部分如果细分的话,包括数据导入方式配置,模型网络结构配置和训练算法配置三个部分。Paddle向用户提供了一个DataProvider的数据提供接口,通过该接口,用户要定义好数据输入方式和数据类型(比如稀疏型还是稠密性,是否为序列型数据等)。后续 的处理,Paddle会根据定义好的参数自行进行优化处理。对于模型网络结构的配置,Paddle已经向用户封装了较多的主流Layer,网络结构的配置简化到只需衔接好上下层间的输入输出。对于训练配置部分,Paddle基本支持目前的所有优化算法,通过修改参数即可实现,不同算法的切换。Mxnet与TensorFlow的训练配置部分大致与Paddle相差无几。但对于数据导入部分,Mxnet虽然也提供了多个基础的I/O父类接口,但特殊情况下,如句子类型数据,用户还需要自己定义一个子类I/O模块来优化数据的导入后的处理方式。此外,Mxnet仅向用户提供了一些运算固定的Layer,更多的是一些矩阵操作符,要配置出像LSTM这样的模型,还需要用户自己编写具体结构。模型训练部分是最为关键的部分,不过基本所有框架都已封装的差不多了。