越来越多的开发者正在使用云服务来训练和运行模型,然而目前看来这种做法的成本较高。不过相比云 GPU 而言,动态分配的云 CPU 就便宜很多了。前苹果员工 Max Woolf 最近测试了云 CPU 阵列在执行 TensorFlow 任务时的效率,并得到了令人满意的结果。利用价格差使用云 CPU 代替 GPU 可以为我们节约不少使用成本。
我一直在使用 Keras 和 TensorFlow 开展一些个人深度学习项目。但是,使用 Amazon EC2 和 Google Compute Engine 等云服务器来训练神经网络模型需要付费。鉴于本人目前并未工作,我必须留意无关花费,并尽可能地具有成本效益。我曾试为了省钱,试过在廉价的 CPU 而不是 GPU 上训练我的深度学习模型,出乎意料的是,这只比在 GPU 上训练略慢一些。因此,我深入了解了这两种类型的实例的定价机制,看看 CPU 是否对我的需求更有用。
在谷歌计算引擎上的 GPU 版本的价格最低是 0.745 美元/小时(通过将0.700美元/小时 的 GPU 裸片连接到0.045美元/小时 n1-standard-1 实例上)。几个月前,谷歌宣布其基于 Intel Skylake CPU 架构的 CPU 实例可以配置多达 64 个虚拟 CPU,更重要的是,它们也可以用在可抢占的 CPU 实例中,它们在 GCE 上最多可以存活 24 小时,随时可能会挂掉(不过很少见),但是它的价格却是标准实例的 20%。具有 64 个 vCPU 和 57.6GB RAM 的可抢占的 n1-highcpu-64 实例加上使用 Skylake CPU 的附加款的总价是 0.509美元/小时,花费大约是 GPU 实例的 2/3。
如果在 64 vCPU 上的模型训练速度与 GPU 版本差不多(或者就略慢那么一点),那么用 CPU 来代替 GPU 就是划算的。但是这些结论都是假设深度学习软件和 GCE 平台硬件的运行效率达到 100%; 如果不能达到(很可能不会),则可以通过缩减 vCPU 的数量和相应的开支来省钱。
由于没有需求,所以没有使用大量 CPU 对深度学习库进行基准化测试方法。同时 GPU 是深入学习硬件的奥卡姆剃刀问题的解决方案。由于谷歌财大气粗,可抢占实例提供了巨大的价格差,所以目前选择使用 CPU 而不是 GPU 进行深度神经学习训练是划算的(尽管这有些违背直觉)。
配置
我已有一个现实运用的深度学习案例的基准化测试脚本,Docker 容器环境,结果日志在另一篇文章中:http://minimaxir.com/2017/06/keras-cntk/
几处小小的改动就可以让这份脚本适用于 CPU 和 GPU 实例(通过设置 CLI 参数)。为了支持最新的 TensorFlow (1.2.1),我重建了 the Docker container,并且创建了 CPU 版本的容器,而不是只安装对应 CPU 版本的 TensorFlow。
此处有个值得注意的 CPU 版本 TensorFlow 特有的现象;如果你是从 pip 安装(按照 official instructions 和教程推荐的方法)并开始用 TensorFlow 训练你的模型,你将会在控制台看到这些警告:
为了修复这些警告并使用 SSE4.2/FMA 这些优化指令集,我们要从源代码编译 TensorFlow,我还创建了第三个 Docker 容器。在新容器中训练模型时,大多数警告不再显示,(spoiler alert)确实在训练时有加速作用。
我们可以使用 Google Compute Engine 测试三个问题:
- Tesla K80 GPU 实例
- 使用 pip 安装 Tensorflow 的 64 Skylake vCPU 实例(同时在 8/16/32 vCPUs 上测试)
- 使用 CPU 指令集(+ 8/16/32 vCPUs)编译 TensorFlow 的 64 Skylake vCPU 实例
结果
对于每个模型架构和软/硬件配置,我通过在训练模型时运行前文提到的测试脚本来计算相对于 GPU 实例训练的总训练时间。在所有的模型中,GPU 实例都应该是最快的训练配置,而且多处理器系统应该比少处理器系统的训练速度更快。
我们从手写数字数据集 MNIST dataset 和常见的使用紧密的全连接层的多层感知机 (MLP) 结构开始。训练时间越短越好。所有低于水平虚线的配置都好过 GPU;反之则不如 GPU。
在这里,GPU 是所有平台配置中最快的,但还有其它奇怪的走势。
32 个 vCPU 和 64 个 vCPU 之间的性能差异不大,编译过的 TensorFlow 库在训练速度上确实有重大提升,但只有 8 和 16 个 vCPU 时才这样。也许在 vCPU 之间进行信息交换的消耗抹去了多 vCPU 的性能优势,又或许是这些开销与编译的 TensorFlow 的 CPU 指令集有所不同。最后,这是一个黑盒子,也就是我为什么更喜欢黑盒测试的硬件配置而不是搞纯理论。
由于 vCPU 数量对训练速度的影响很小,那么显然减少它的数量是有好处的。对于每个模型架构和配置,我计算了相对于 GPU 实例训练成本的归一化训练成本。因为 GCE 实例成本是按比例计算的(不像 Amazon EC2),我们可以将实验运行的总秒数乘以每秒实例的成本来简单地计算实验成本。理想情况下,我们希望最小化成本。
对于这个问题,CPU 数量越少越划算。现在我们来看看在同一数据集上使用卷积神经网络解决数字识别任务的情况:
不出意料,在卷积网络上 GPU 的训练速度比任何 CPU 方案快两倍不止,不过成本结构仍然相同,除了 64 vCPU 比 GPU 成本方面更差,32 个 vCPU 训练速度甚至快过 64 个 vCPU。我们来深入了解下卷积神经网络,CIFAR-10 图像分类数据集,以及一个使用深层卷积网络加多层感知机进行图像分类的模型(类似于 VGG-16 架构)。
与简单的卷积神经网络(CNN)性质类似,尽管在已编译 TensorFlow 库的实例下 CPU 的表现更好。
用在 IMDb 影评数据集上的 fasttext 算法能判别一个影评是正面的还是负面的,相对于其它算法,该算法对于影评分类最为快速。
在这种情况下,GPU 比 CPU 快得多。CPU 数量较少的好处并不是很明显。尽管如此,官方的 fasttext 算法实现是为大型 CPU 集群设计的,并且可以更好地处理并行化。
双向长短期记忆网络(LSTM)极其善于处理类似 IMDb 影评这样的文本数据,但是在我发布基准测试文章后,Hacker News 上的一些评论指出 TensorFlow 使用的是一个在 GPU 上的 LSTM 的低效实现,因此,实际上这种差异可能还会更加明显。
等等,什么情况?双向 LSTM 的 GPU 训练速度是任意 CPU 配置的两倍慢?哇。(实际上,基准化测试使用 Keras LSTM 默认 implementation=0,这对 CPU 而言更好,而在 GPU 上 implementation=2 更好,但不应该导致这么大的差异)
最后,尼采作品的 LSTM 文字生成器与其他架构的表现相似,CPU 并没有对 GPU 造成严重威胁。
结论
事实证明,使用 64 个 vCPU 不利于深入学习,因为当前的软/硬件架构无法充分利用所有 CPU 的计算性能,通常会有与 32 个 vCPU 完全相同(甚至更差)的性能。就平衡训练速度与成本来说,使用 16 个 vCPU 加编译的 TensorFlow 来训练模型貌似是最佳选择。编译过的 TensorFlow 库的 30%-40%的速度提升是一个意想不到的惊喜,但令我震惊的是,虽然增益不菲,但 Google 并未提供具有这些 CPU 加速功能的 TensorFlow 的预编译版本。
这里显示的成本优势只有在可抢占的情况下才可能是有价值的;Google Compute Engine 上的常规 high-CPU 实例价格约为 5 倍,因此可以完全消除成本优势。规模经济万岁!
使用云 CPU 训练方式的一个主要的隐含假设是,你不需要像 ASAP 那样的训练过的模型。在专业用例中,时间及其宝贵,但在个人用例中,我们可以训练一个模型一整夜,这对个人来说是个很好很划算的选择,也是我做出的选择。