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 = True
        print('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) 是一个用于控制是否使用确定性算法的选项。启用确定性算法可以确保每次运行的结果一致,但在某些情况下可能会导致性能下降。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/872502.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis安装步骤——离线安装与在线安装详解

Linux环境下Redis的离线安装与在线安装详细步骤 环境信息一、离线安装1、安装环境2、下载redis安装包3、上传到服务器并解压4、编译redis5、安装redis6、配置redis(基础配置)7、启动redis8、本机访问redis9、远程访问redis 二、在线安装1、更新yum源2、安…

【LeetCode】01.两数之和

题目要求 做题链接:1.两数之和 解题思路 我们这道题是在nums数组中找到两个两个数使得他们的和为target,最简单的方法就是暴力枚举一遍即可,时间复杂度为O(N),空间复杂度为O(1)。…

域内安全:委派攻击

目录 域委派 非約束性委派攻击: 主动访问: 被动访问(利用打印机漏洞) 约束性委派攻击: 域委派 域委派是指将域内用户的权限委派给服务账户,使得服务账号能够以用户的权限在域内展开活动。 委派是域中…

P4560 [IOI2014] Wall 砖墙

*原题链接* 做法:线段树 一道比较基础的线段树练手题,区间赋值,在修改时加些判断剪枝。 对于add操作,如果此时区间里的最小值都大于等于h的话,就没必要操作,如果最大值都小于h的话,就直接区间…

坐牢第三十五天(c++)

一.作业 1.使用模版类自定义栈 代码&#xff1a; #include <iostream> using namespace std; template<typename T> // 封装一个栈 class stcak { private:T *data; //int max_size; // 最大容量int top; // 下标 public:// 无参构造函数stcak();// 有参…

【全志H616】【开源】 ARM-Linux 智能分拣项目:阿里云、网络编程、图像识别

【全志H616】【开源】 ARM-Linux 智能分拣项目&#xff1a;阿里云、网络编程、图像识 文章目录 【全志H616】【开源】 ARM-Linux 智能分拣项目&#xff1a;阿里云、网络编程、图像识1、实现功能2、软件及所需环境3、逻辑流程图及简述3.1 完整逻辑流程图3.2 硬件接线3.3 功能简述…

部署project_exam_system项目——及容器的编排

&#xff08;一&#xff09;安装docker、编辑daemon.json文件、安装docker-compose编排容器、启动docker 1.环境准备 [rootdocker--1 ~]# rz -Erz waiting to receive.[rootdocker--1 ~]# lsanaconda-ks.cfg docker.sh[rootdocker--1 ~]# source docker.sh [rootdocker--1 ~…

基于Flink的流式计算可视化开发实践之配置->任务生成->任务部署过程

1. 引言 在我们大数据平台(XSailboat)的DataStudio模块中实现了基于Hive的业务流程开发和基于Flink的实时计算管道开发。 DataStudio是用来进行数据开发的&#xff0c;属于开发环境&#xff0c;另外还有任务运维模块&#xff0c;负责离线分析任务和实时计算任务在生产环境的部…

30岁程序员的焦虑:转行还是继续死磕?现在什么方向更有前景?

最适合转入AI大模型的莫过于程序员和在读大学生了吧。 对于程序员来说&#xff0c;码农之路并不是一帆风顺。对于每一个入行IT业的社会青年来说&#xff0c;谁不是抱着想要成为最高峰的技术大咖或者跃进管理岗的小目标&#xff1f; 然而往往更多的人并非互联网吹捧的如此耀眼…

低代码平台:加速企业制造业数字化转型的新引擎

近期&#xff0c;国家发布了中小企业数字化转型试点城市的政策&#xff0c;旨在通过先行先试&#xff0c;探索支持制造业特别是汽车制造行业数字化转型的有效模式。这一政策的出台&#xff0c;为汽车制造企业的数字化转型提供了强有力的政策支持和方向指引&#xff0c;标志着汽…

【论文速读】| SEAS:大语言模型的自进化对抗性安全优化

本次分享论文&#xff1a;SEAS: Self-Evolving Adversarial Safety Optimization for Large Language Models 基本信息 原文作者: Muxi Diao, Rumei Li, Shiyang Liu, Guogang Liao, Jingang Wang, Xunliang Cai, Weiran Xu 作者单位: 北京邮电大学, 美团 关键词: 大语言模…

vue.js项目实战案例详细源码讲解

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; 为帮助大家更好地掌握Vue.js项目的开发流程&#xff0c;我将为你讲解一个完整的Vue.js实战案例&#xff0c;并提供详细的源码解析。这个案例将涵盖从项目创建到实现各种功能模块的全过程&#xff0c;适合用于…

基于空间结构光场照明的三维单像素成像

单像素成像是一种新兴的计算成像技术。该技术使用不具备空间分辨能力的单像素探测器来获取目标物体或场景的空间信息。单像素探测器具有高的时间分辨率、光探测效率和探测带宽&#xff0c;因此单像素光学成像技术在散射、弱光等复杂环境下相较于传统面阵成像技术展现了很大优势…

面试题:软件测试缺陷产生的原因有哪些?

软件缺陷产生的原因多种多样&#xff0c;一般可能有以下几种原因&#xff1a; 1.需求表述、理解、编写引起的错误。 2.系统架构设计引起的错误。 3.开发过程缺乏有效的沟通及监督&#xff0c;甚至没有沟通或监督。 4.程序员编程中产生的错误。 5.软件开发工具本身隐藏的问…

哨兵排序算法

代码展示 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h>#define MAXSIZE 20 //直接排序 typedef struct {int r[MAXSIZE 1];int length; } SqList; int InsertSort(SqList* L) {int i, j;for (i 2; i < L->length; i){if (L-…

mysql自增主键插入后返回id与实际插入id不同

加入这一段即可 GeneratedValue(strategy GenerationType.IDENTITY)

张飞硬件10-TVS管篇笔记

TVS管的原理 TVS或称瞬变电压抑制二极管&#xff0c;是在二极管工艺基础上发展起来的新产品&#xff0c;其电路符号和普通稳压管相同&#xff0c;外形也与普通二极管无异。当TVS管两端经受瞬间的高能量冲击时&#xff0c;它能以极高的速度将其阻抗骤然降低&#xff0c;同时吸收…

el-table 单元格,双击编辑

el-table 单元格&#xff0c;双击编辑 实现效果 代码如下 <template><el-table :data"tableData" style"width: 100%"><el-table-column prop"name" label"姓名" width"180"><template slot-scope&q…

【机器学习】梯度提升和随机森林的概念、两者在python中的实例以及梯度提升和随机森林的区别

引言 梯度提升&#xff08;Gradient Boosting&#xff09;是一种强大的机器学习技术&#xff0c;它通过迭代地训练决策树来最小化损失函数&#xff0c;以提高模型的预测性能 随机森林&#xff08;Random Forest&#xff09;是一种基于树的集成学习算法&#xff0c;它通过组合多…

Java队列详细解释

队列 一、什么是队列&#xff08;Queue&#xff09; java队列是一种线性数据结构&#xff0c;它的特点是先进先出。在队列中&#xff0c;元素的添加&#xff08;入队&#xff09;操作在队尾进行&#xff0c;而元素的移除&#xff08;出队&#xff09;操作则在队头进行。因此&a…