何为最优
最优并不是绝对的,而是需要针对具体的应用场景而言.在深度学习应用中,训练时我们往往对训练速度有要求,希望越快越好,也就意味着能够在更短的时间训练完我们的模型,更小的调整参数的成本;而对于随着网络模型的深度加大,模型本身训练时所占用的显存空间很大,这时候就要求我们的选取的卷积算法能够竟可能的少占用临时显存空间.综上,这是一个时间与空间的权衡,本文会结合当前最新的CuDNN分析如何实现自动选取最优卷积算法.
时间与空间的权衡
速度越快的算法往往依赖于更大的临时空间,也就是所谓空间换时间,所以最优的卷积算法还是应该结合我们具体的需求来定义.
问题来源?CuDNN
CuDNN提供了多种卷积算法的实现,同时也提供了两类API,分别为get/find,用户自行调用得到满足特定条件下的最优卷积算法实现.其中GET类型方法是根据经验得到对应的卷积算法,比如输入的layout, filter的大小,卷积输入的数据类型等等,这个查找过程是常数级别,笔者亲测过.这个方法的好处是调用简单,CuDNN根据一些经验设定简易判断,同时给定是否有空间限制的选项,比如有workspace_limit, fastest,no_workspace_limit等.但是,通过这个API获得的卷积算法并不一定是最快的,读者可以自行验证.另外就是find类型的接口,原理是遍历一遍所有的卷积算法,返回一个perf结果,包括每个算法实际运行所需的时间以及临时空间大小,如果该卷积算法不支持当前的输入数据,那么状态就不为CUDNN_STATUS_SUCCESS.通过这种方式得到是最具有说服力,实测也是最快的,如果对空间存在限制,那么可以根据返回的perf结果进一步限制.
出于这个的原因,如何根据当前的应用场景和卷积输入,选取最优的卷积算法就成为一个值得考量的问题.本文主要是强调如何加速训练过程,而讨论的重点也是通过find方法.
Auto-tune
前一小节提到CuDNN提供了应对不同需求的卷积算法接口,本小节详细讨论一