torch.backends.cudnn.benchmark和torch.use_deterministic_algorithms总结学习记录

本文主要是介绍torch.backends.cudnn.benchmark和torch.use_deterministic_algorithms总结学习记录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

经常使用PyTorch框架的应该对于torch.backends.cudnn.benchmark和torch.use_deterministic_algorithms这两个语句并不陌生,在以往开发项目的时候可能专门化花时间去了解过,也可能只是浅尝辄止简单有关注过,正好今天再次遇到了就想着总结梳理一下。

torch.backends.cudnn.benchmark 是 PyTorch 中的一个设置选项,用于优化卷积神经网络(CNN)的计算效率。这个选项可以显著加速卷积操作,尤其是在使用 NVIDIA cuDNN 库时。

背景简介

卷积层是卷积神经网络中的最重要的部分,也往往是运算量最大的部分。对于卷积这个操作来说,其实现方式是多种多样的。最简单的实现方式就是使用多层循环嵌套,对于每张输入图像,对于每个要输出的通道,对于每个输入的通道,选取一个区域,同指定卷积核进行卷积操作,然后逐行滑动,直到整张图像都处理完毕,这个方法一般被称为 direct 法,这个方法虽然简单,但是看到这么多循环,我们就知道效率在一般情况下不会很高了。除此之外,实现卷积层的算法还有基于 GEMM (General Matrix Multiply) 的,基于 FFT 的,基于 Winograd 算法的等等,每种卷积算法,都有其特有的一些优势,比如有的算法在卷积核大的情况下,速度很快;比如有的算法在某些情况下内存使用比较小。给定一个卷积神经网络(比如 ResNet-101),给定输入图片的尺寸,给定硬件平台,实现这个网络最简单的方法就是对所有卷积层都采用相同的卷积算法(比如 direct 算法),但是这样运行肯定不是最优的;比较好的方法是,我们可以预先进行一些简单的优化测试,在每一个卷积层中选择最适合(最快)它的卷积算法,决定好每层最快的算法之后,我们再运行整个网络,这样效率就会提升不少。

这里有一个问题,为什么我们可以提前选择每层的算法,即使每次我们送入网络训练的图片是不一样的?即每次网络的输入都是变化的,那么我怎么确保提前选出来的最优算法同样也适用于这个输入呢?原因就是,对于给定输入来说,其具体值的大小是不影响卷积的运行时间的,只有其尺寸才会影响。举例来说,我们只要固定输入大小都是 (8, 64, 224, 224),即 batch_size 为 8,输入的通道为 64,宽和高为 224,那么卷积层的运行时间都是几乎不变的,无论其中每个像素具体的值是 0.1 还是 1000。这样的话,因为我们固定了模型输入的尺寸大小,所以对每个卷积层来说,其接受的输入尺寸都是静态的,固定不变的,在提前做优化的时候我们只要使用随机初始化的相应尺寸的输入进行测试和选择就行了。

1. 什么是 cuDNN?

cuDNN 是 NVIDIA CUDA 深度神经网络库(CUDA Deep Neural Network library)的缩写。它是一个高度优化的库,专门用于加速深度学习中的卷积操作。cuDNN 提供了许多高效的算法,可以自动选择最适合当前硬件和输入尺寸的算法。

2. torch.backends.cudnn.benchmark 的作用

torch.backends.cudnn.benchmark 是一个布尔值选项,默认情况下为 False。当设置为 True 时,cuDNN 会启用自动搜索和选择最优算法的机制。具体来说:

  • 自动搜索最优算法: cuDNN 会根据输入的尺寸和网络结构,自动搜索并选择最优的卷积算法。这个过程可能需要一些时间,但一旦找到最优算法,后续的卷积操作会显著加速。

  • 适合固定输入尺寸: 这个选项最适合在输入尺寸固定的情况下使用。如果输入尺寸经常变化,cuDNN 每次都需要重新搜索最优算法,这可能会导致性能下降。

3. 如何使用 torch.backends.cudnn.benchmark

你可以在代码中设置 torch.backends.cudnn.benchmark 为 True,如下所示:

import torch# 启用 cuDNN 自动搜索最优算法
if torch.cuda.is_available():device = torch.device('cuda')print('Using GPU: ', torch.cuda.get_device_name(0))if args.use_benchmark:torch.backends.cudnn.benchmark = Trueprint('Using cudnn.benchmark.')
else:device = torch.device('cpu')print('Warning! Using CPU.')# 你的模型和训练代码
model = YourModel()
model.to('cuda')
# ...

4. 优缺点

  • 优点:

    • 加速卷积操作: 通过自动选择最优算法,可以显著加速卷积操作,尤其是在大规模模型和数据集上。

    • 简化代码: 不需要手动选择和调整卷积算法,cuDNN 会自动处理。

  • 缺点:

    • 初始化时间增加: 在第一次运行时,cuDNN 需要搜索最优算法,这可能会增加初始化时间。

    • 不适合动态输入尺寸: 如果输入尺寸经常变化,cuDNN 每次都需要重新搜索最优算法,这可能会导致性能下降。

5. 适用场景

  • 固定输入尺寸: 如果你的输入尺寸是固定的(例如图像分类任务中的固定尺寸图像),启用 torch.backends.cudnn.benchmark 可以显著提升性能。

  • 大规模模型和数据集: 在大规模模型和数据集上,卷积操作的加速效果尤为明显。

6. 注意事项

  • 动态输入尺寸: 如果你的输入尺寸经常变化(例如在目标检测或生成对抗网络中),建议不要启用 torch.backends.cudnn.benchmark,以免性能下降。

  • 调试和分析: 在调试和分析模型时,建议将 torch.backends.cudnn.benchmark 设置为 False,以确保每次运行的结果一致。

torch.use_deterministic_algorithms(False) 是 PyTorch 中的一个设置选项,用于控制是否使用确定性算法。确定性算法是指在相同的输入和相同的硬件环境下,每次运行都会产生相同的结果。以下是详细介绍:

1. 什么是确定性算法?

确定性算法是指在相同的输入和相同的硬件环境下,每次运行都会产生相同的结果。这种特性在调试和复现实验结果时非常有用,因为它可以确保每次运行的结果都是一致的。

2. torch.use_deterministic_algorithms 的作用

torch.use_deterministic_algorithms 是一个布尔值选项,默认情况下为 False。当设置为 True 时,PyTorch 会尽可能使用确定性算法,以确保每次运行的结果一致。具体来说:

  • 确定性算法: 启用确定性算法后,PyTorch 会使用那些在相同输入下总是产生相同输出的算法。这包括一些随机数生成器、卷积算法等。

  • 性能影响: 使用确定性算法可能会导致性能下降,因为某些确定性算法可能不如非确定性算法高效。

3. 如何使用 torch.use_deterministic_algorithms

你可以在代码中设置 torch.use_deterministic_algorithms 为 True 或 False,如下所示:

import torch# 启用确定性算法
torch.use_deterministic_algorithms(True)# 你的模型和训练代码
model = YourModel()
model.to('cuda')
# ...

我第一次注意到torch.use_deterministic_algorithms的时候是在基于YOLOv5开发自己的目标检测模型的时候, 如下:

在我自己的机器上直接运行的话会报错,需要将其改为如下代码:

torch.use_deterministic_algorithms(False)

我刚才专门又去看了下github里面官方的项目,发现官网最新的代码已经把这句代码删除了,感兴趣的话可以自行看下,如下所示:

4. 优缺点

  • 优点:

    • 结果可复现: 启用确定性算法可以确保每次运行的结果一致,这对于调试和复现实验结果非常有用。

    • 简化调试: 在调试过程中,确定性算法可以帮助你更容易地找到问题的根源,因为每次运行的结果都是相同的。

  • 缺点:

    • 性能下降: 使用确定性算法可能会导致性能下降,因为某些确定性算法可能不如非确定性算法高效。

    • 功能限制: 某些操作可能没有确定性实现,因此在这些情况下,启用确定性算法可能会导致错误或限制某些功能。

5. 适用场景

  • 调试和复现: 在调试和复现实验结果时,启用确定性算法非常有用,因为它可以确保每次运行的结果一致。

  • 敏感应用: 在某些对结果一致性要求非常高的应用中(例如金融、安全等领域),确定性算法可能是一个重要的考虑因素。

6. 注意事项

  • 性能影响: 启用确定性算法可能会导致性能下降,因此在生产环境中,你可能需要权衡性能和结果一致性之间的平衡。

  • 功能限制: 某些操作可能没有确定性实现,因此在启用确定性算法时,需要注意这些限制。

7. 相关设置

  • torch.backends.cudnn.deterministic: 这个选项与 torch.use_deterministic_algorithms 类似,但它主要影响 cuDNN 库的行为。当设置为 True 时,cuDNN 会使用确定性算法。

总结

torch.backends.cudnn.benchmark 是一个强大的工具,可以显著加速卷积神经网络的计算效率。通过启用这个选项,cuDNN 会自动搜索并选择最优的卷积算法,从而提升性能。然而,它最适合在输入尺寸固定的情况下使用,如果输入尺寸经常变化,可能会导致性能下降。torch.use_deterministic_algorithms(False) 是一个用于控制是否使用确定性算法的选项。启用确定性算法可以确保每次运行的结果一致,但在某些情况下可能会导致性能下降。

这篇关于torch.backends.cudnn.benchmark和torch.use_deterministic_algorithms总结学习记录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1142649

相关文章

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

java常见报错及解决方案总结

《java常见报错及解决方案总结》:本文主要介绍Java编程中常见错误类型及示例,包括语法错误、空指针异常、数组下标越界、类型转换异常、文件未找到异常、除以零异常、非法线程操作异常、方法未定义异常... 目录1. 语法错误 (Syntax Errors)示例 1:解决方案:2. 空指针异常 (NullPoi

Spring Boot中定时任务Cron表达式的终极指南最佳实践记录

《SpringBoot中定时任务Cron表达式的终极指南最佳实践记录》本文详细介绍了SpringBoot中定时任务的实现方法,特别是Cron表达式的使用技巧和高级用法,从基础语法到复杂场景,从快速启... 目录一、Cron表达式基础1.1 Cron表达式结构1.2 核心语法规则二、Spring Boot中定

Java反转字符串的五种方法总结

《Java反转字符串的五种方法总结》:本文主要介绍五种在Java中反转字符串的方法,包括使用StringBuilder的reverse()方法、字符数组、自定义StringBuilder方法、直接... 目录前言方法一:使用StringBuilder的reverse()方法方法二:使用字符数组方法三:使用自

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

国内环境搭建私有知识问答库踩坑记录(ollama+deepseek+ragflow)

《国内环境搭建私有知识问答库踩坑记录(ollama+deepseek+ragflow)》本文给大家利用deepseek模型搭建私有知识问答库的详细步骤和遇到的问题及解决办法,感兴趣的朋友一起看看吧... 目录1. 第1步大家在安装完ollama后,需要到系统环境变量中添加两个变量2. 第3步 “在cmd中

Python依赖库的几种离线安装方法总结

《Python依赖库的几种离线安装方法总结》:本文主要介绍如何在Python中使用pip工具进行依赖库的安装和管理,包括如何导出和导入依赖包列表、如何下载和安装单个或多个库包及其依赖,以及如何指定... 目录前言一、如何copy一个python环境二、如何下载一个包及其依赖并安装三、如何导出requirem

Spring Retry 实现乐观锁重试实践记录

《SpringRetry实现乐观锁重试实践记录》本文介绍了在秒杀商品SKU表中使用乐观锁和MybatisPlus配置乐观锁的方法,并分析了测试环境和生产环境的隔离级别对乐观锁的影响,通过简单验证,... 目录一、场景分析 二、简单验证 2.1、可重复读 2.2、读已提交 三、最佳实践 3.1、配置重试模板

在 Spring Boot 中使用异步线程时的 HttpServletRequest 复用问题记录

《在SpringBoot中使用异步线程时的HttpServletRequest复用问题记录》文章讨论了在SpringBoot中使用异步线程时,由于HttpServletRequest复用导致... 目录一、问题描述:异步线程操作导致请求复用时 Cookie 解析失败1. 场景背景2. 问题根源二、问题详细分