当前位置: 首页 > 科技观察

将PyTorch投入生产时的5个常见错误

时间:2023-03-22 11:15:29 科技观察

简介本文列出了将PyTorch投入生产时容易遇到的5个错误。ML很有趣,ML很流行,ML无处不在。大多数公司要么使用TensorFlow,要么使用PyTorch,也有一些老家伙喜欢Caffe。虽然大多数教程和在线教程都使用TensofFlow,但我的大部分经验都是使用PyTorch。在这里,我想分享在生产中使用PyTorch时最常见的5个错误。考虑使用CPU?使用多线程?使用更多GPU显存?这些坑我们都踩过。错误#1——在推理模式下保存动态图如果你以前使用过TensorFlow,那么你可能知道TensorFlow和PyTorch之间的主要区别——静态图和动态图。调试TensorFlow非常困难,因为每次模型更改时都需要重新构建图形。这需要时间、努力和你的希望。当然,TensorFlow现在更好了。通常,为了使调试更容易,ML框架使用动态图,这与PyTorch中所谓的变量相关。您使用的每个变量都链接到前一个变量以建立反向传播的关系。这是它在实践中的样子:在大多数情况下,您希望在训练模型后优化所有计算。如果你看一下torch的界面,有很多选项,特别是在优化方面。evalmode、detach和no_grad方法引起了很多混乱。让我解释一下它们是如何工作的。模型训练部署好后,下面是你关心的:速度、速度、CUDA内存不足异常。为了加速PyTorch模型,您需要将其切换到评估模式。它通知所有层在推理模式下使用batchnorm和dropout层(只是没有dropout)。现在,有一种分离方法可以将变量从其计算图中分离出来。当您从头开始构建模型时它很有用,但当您想要重用来自SOTA的模型时则不太有用。一个更全局的解决方案是在正向传递期间在上下文中使用torch.no_grad。这节省了内存消耗,因为不必在结果中存储图中变量的梯度。它节省内存并简化计算,因此,您可以获得更快的速度和更少的内存使用。错误#2-未启用cudnn优化算法您可以在nn.Module中设置许多布尔标志,您必须注意其中一个。使用cudnn.benchmark=True来优化cudnn。通过设置cudnn.enabled=True,可以确保cudnn确实在寻找最优算法。NVIDIA为您提供了许多可以从中受益的优化方面的魔力。请注意,您的数据必须在GPU上,模型输入大小不应更改。数据的形状变化越大,可以做的优化就越少。例如,为了规范化数据,可以对图像进行预处理。简而言之,可以有变化,但不能太多。错误#3-重用JIT编译PyTorch提供了一种简单的方法来优化和重用来自不同语言的模型(参见Python-To-Cpp)。如果您足够勇敢,您可能会更有创意并将您的模型嵌入其他语言。JIT编译允许优化计算图,同时保持输入的形状不变。它的意思是,如果您的数据形状变化不大(参见错误#2),那么JIT是一个选项。老实说,与上面提到的no_grad和cudnn相比,它并没有太大的区别,但可能会有。这只是第一个版本,具有巨大的潜力。请注意,如果您的模型中有条件(这在RNN中很常见),它将不起作用。错误#4——尝试扩展CPUGPU的成本很高,云VM也是如此。即使使用AWS,一个实例每天的费用约为100美元(最低价格为0.7美元/小时)。也许有人会想“如果我使用5个CPU而不是1个GPU呢?”。试过的人都知道这是死路一条。是的,你可以为CPU优化一个模型,但最终它仍然会比GPU慢。相信我,我强烈建议忘记这个想法。错误#5—处理向量而不是矩阵cudnn-检查no_grad-检查GPU是否具有正确版本的CUDA-检查JIT编译-检查一切就绪,还有什么要做?现在是时候使用一点数学了。如果您还记得大多数神经网络是如何使用所谓的张量进行训练的。张量在数学上是一个n维数组或多线性几何向量。您可以做的是将输入(如果您有足够的时间)分组为张量或矩阵,并将其输入到您的模型中。例如,使用图像数组作为矩阵发送到PyTorch。性能增益等于同时传递的对象数。这是一个显而易见的解决方案,但很少有人真正使用它,因为大多数时候对象是一个一个地处理的,在一个过程中设置这样的流程可能有点困难。别担心,你会成功的!