人工智能应用专家Sreenidhi Anand和Mario Michael Krell博士[1]在使用Graphcore PopVision分析工具方面经验丰富,他们认为这些工具在优化模型存储和性能时非常有用。
发现问题
Graphcore的一位客户希望使用RetinaNet[2]模型来执行视频帧中的高通量特征检测。这个网络的输出是一组围绕着它在每一帧中检测到的“相关物体”的矩形边框,它将这些方框传递给其他系统以采取下一步行动。
检测到的相关物体周围的矩形边框
(从Google images捕获的样本图像)
“我们预期每张图像有5到10个方框,但我们得到的结果是大约10万个。”Sreenidhi表示,“一般的预期是10到15个物体”。
每张图像10万个方框显然太多了,用处不大——检测系统会因冗余信息而超载。因此他们增加了一个非极大值抑制(Non-Maximum Suppression,NMS)过滤器,将那些识别相同物体的方框合并起来,然后将它们按置信度排序,以便下游系统能够根据视野中呈现的这些物体决定采取什么行动。
但就其本身而言,这个系统处理图像的速度还是太慢了。为了解其中的原因,他们打开了PopVision计算图分析工具应用程序,并查看了Poplar在模型执行时产生的执行跟踪。
执行跟踪报告显示针对IPU时钟周期所执行的程序步骤,您可以用这个报告来确定哪些功能占用了多少比例的可用周期,甚至可以随时显示IPU上每个tile的活动。
大部分的跟踪显示了系统的预期行为,即RetinaNet模型的所有程序步骤都如期出现。但从BSP的跟踪中可以清楚地看到,IPU的大部分活动都被等待同步的tile占用了(黄色)。当他们放大NMS的排序功能时,是什么导致了系统中的瓶颈立刻就非常清晰了。
在这里,您可以看到Sreenidhi运行的程序的执行轨迹,放大后显示了工作中的排序算法的实例。顶部的可视化图显示了IPU上程序执行的摘要,类似于火焰图。下面的BSP跟踪显示了IPU上的tile随着时间推移的活动,每个tile都显示为一条水平线(顶部为tile 0)。
IPU在批量同步并行(BSP)[3]范式上运行,这意味着在任何时候,一个tile要么在进行计算(粉色),要么在等待与其他tile同步(黄色),要么在与其他tile交换数据(蓝色)。Poplar软件编译程序步骤,并以能够最好地利用IPU并行性的方式将它们分配给可用的tile。为了能够以最高效率工作,IPU需要同时执行最大数量的程序步骤并将等待与其他tile同步的tile数量保持在最少的水平。
在上图中,您可以看到程序执行在各个tile之间高效进行,但是当执行排序函数时(右边的那些重复块),几乎每个tile都进入了同步状态(黄色),等待任何正在执行的tile完成它们的工作。有一个tile的BSP轨迹大部分时间是红色的(表明它正在计算),所有其他的tile都处于闲置状态,等待它完成排序工作,然后这些tile才能被再次使用。
由于排序算法需要多次传递数据,然后才能继续传递有序的结果列表,这个瓶颈在执行过程中多次重复出现,导致整个模型的执行速度远远低于要求。这个库的排序功能最初被设计为使用尽可能少的tile,以保持所需的存储就在附近,但这意味着它只有线性计算效率,并经常在试图完成排序的最后阶段时耗尽存储,合并其所有的排序块。
为并行排序创建一个新的自定义操作
Sreenidhi开始测试现有的排序功能,以了解为什么在IPU上的编译和运行需要这么长的时间。他把批次越来越大的数字交给程序进行排序:100、500、1000……很快他发现,当他要求程序对超过5000个数字进行排序时,就需要很长的时间才能完成编译:编译器无法找到可以安排搜索的存储管理方法。这看起来非同寻常:排序函数可能很慢,效率很低,但您总是可以期待它们最终能够完成。

PopLibs、PopART,以及TensorFlow等高层框架都有标准的库操作(“ops”),例如矩阵乘法和还原函数,这些操作贯穿于许多模型定义中。这些函数中的大多数都针对在IPU上运行进行了高度优化,但有时我们会发现在某个特定的应用程序中需要提高核心代码的效率。
高效地使用存储、高数据带宽和低时延都是机器学习系统的理想特征。优化一个模型,使其运行良好,有时需要一个新的自定义操作来减少所需的存储,或减少几毫秒的执行时间。如果其他解决方案无济于事,可能需要一个自定义操作。(请在此[4]查看我们的自定义操作创建指南)。
软件团队成立了一个工作小组,研究哪种搜索算法可能对我们现有的硬件和软件栈来说最有效,软件工程师Jake Hall认为双调排序[5]会很适合他们的需求。这种排序有几个变体,需要许多嵌套比较、交换和合并操作,但很明显,这种算法会很适合IPU:尽可能多的tile将能够被用来进行并行工作,这意味着没有tile会被留下“承担所有的负载”,并导致他们所面临的那种瓶颈。
找到“亮眼”的解决方案
在这个算法的早期实验中,所有的IPU tile都被投入进去,得到了这个BSP跨tile活动的有趣图像。
在这里您可以看到,IPU上的所有tile都被更多地使用,没有一个tile需要长时间等待与其他tile同步。您也可以看到排序的周期性模式,它们在逐渐完成排序时显示出单个排序和合并操作的赏心悦目的二进制模式。
然而,该团队很快就发现,一个稍有不同的双调排序变体可以使其在IPU上运行得更加高效。软件工程师Tom Murray实施了这一变体。在设计一个新的算法时,总是会有一些权衡,必须考虑许多指标:算法的速度,tile之间交换数据的时间,以及实施算法所需的代码规模。
找到合适的解决方案
最终,他们选择的一个主要因素是算法的代码规模最小化。他们选择了一种可以在tile上更清晰地分散存储使用和计算负载的变体。
当他们使用新的自定义排序操作重新编译和运行程序时,编译速度要快得多,吞吐量和时延也得到了极大的改善。经过对新的排序功能进行的几次迭代优化后,执行跟踪的对应部分显示tile效率明显提升:
这个排序函数的实例清晰地显示了通过使用新的自定义操作并行tile计算的使用效率会有多大的提升。每个tile的负载很好地分布在tile之间,并且每个tile都不会等待很长时间才能将其排序的批次与其他tile的批次合并。它们一起工作,但又彼此独立,将排序分解成可管理的部分。
这就是他们所需的解决方案,使整个系统达到客户所需的用于实时视频目标检测的性能。随着排序的速度加快,并且存储使用效率提高,它们可以增加批次规模,提供更大的吞吐量并降低时延。可以排序的项目数量不再受限于新操作:只要是适合IPU存储的项目,您都可以进行排序。
因此,一个新的[6]排序自定义操作现已被纳入标准PopLibs库的一部分,使得将来任何人都可以从中受益。就像IPU tile本身一样,共享工作可以带来真正的优势。
为什么工具很重要
就像我们读到的许多“突破性时刻”一样,有一个想法很难撼动:我上面描述的所有事件都是线性、有序的决策,逐步朝着目标前进,然而现实生活并非如此有条理,有许许多多的来回往复、实验、优化、放弃,最终找到最有希望通向成功的道路。我们并非总能看清这条道路的远处将通向何方,我们的思想也并非总能轻易接受像IPU这样的大规模复杂系统向我们提供的大量信息。
关于IPU性能的信息并非多多益善,尤其是如果我们无法在问题的背景下理解这些数据。然而,将这些数据可视化,利用到我们的大脑已经拥有的专长。我们擅长理解图像,尤其是它们将许多数据点组合成可以在屏幕上有意义地表示的单个概念时。
Sreenidhi和Mario在构建和优化机器学习模型方面拥有深厚的经验,并且将PopVision分析工具作为他们研究的一个组成部分,因此他们可以轻松地看到问题,并继续改进它,直到解决方案“看起来正确”。一个好的工具应该改变您对世界的看法,让您以以前无法想象的方式创造、构建和理解这个世界。
您可以在此[7]下载用于MacOS、Linux和Windows的最新PopVision工具。我们的文档门户还包含用于从IPU程序捕获配置文件的指南[8]和教程[9]
[1]https://medium.com/@dr.mario
[2]https://paperswithcode.com/method/retinanet
[3]https://en.wikipedia.org/wiki/Bulk_synchronous_parallel
[4]https://docs.graphcore.ai/projects/custom-ops/en/latest/index.html
[5]https://en.wikipedia.org/wiki/Bitonic_sorter
[6]https://github.com/graphcore/poplibs/commit/f69d60c6f4d6d612a94759c62a3a223188904fbd
[7]https://www.graphcore.ai/developer/popvision-tools
[8]https://docs.graphcore.ai/en/latest/software.html#profiling-and-debugging
[9]https://docs.graphcore.ai/en/latest/examples.html#popvision-profiling-and-analysis-tools
获取更多Graphcore资讯,阅读深度技术文章,并与其他创新者们一起交流,请至中国官网graphcore.cn,以及关注Graphcore微信、微博和知乎创新社区。
Graphcore中国官网
Graphcore官方微信
Graphcore微博创新社区
Graphcore知乎创新社区
点击阅读原文,查看英文blog。
继续阅读
阅读原文