Pytorch原生AMP支持使用方法(1.6版本)

摘要:
在Python 1.5版及更早版本中,amp功能可以通过NVIDIA生产的插件apex实现。从Python 1.6版开始,Python将amp的函数导入到位于torch.cuda.amp模块下的官方库中。为了实现自动混合精度训练,需要结合以下两个模块:火炬。库达。放大器。autocast:autocast主要用作上下文管理器或装饰器,以确定混合精度的范围。

AMP:Automatic mixed precision,自动混合精度,可以在神经网络推理过程中,针对不同的层,采用不同的数据精度进行计算,从而实现节省显存和加快速度的目的。

在Pytorch 1.5版本及以前,通过NVIDIA出品的插件apex,可以实现amp功能。

从Pytorch 1.6版本以后,Pytorch将amp的功能吸收入官方库,位于torch.cuda.amp模块下。

本文为针对官方文档主要内容的简要翻译和自己的理解。

1. Introduction

torch.cuda.amp提供了对混合精度的支持。为实现自动混合精度训练,需要结合使用如下两个模块:

2. Typical Mixed Precision Training

一个典型的amp应用示例如下:

# 定义模型和优化器
model = Net().cuda()
optimizer = optim.SGD(model.parameters(), ...)

# 在训练最开始定义GradScalar的实例
scaler = GradScaler()

for epoch in epochs:
    for input, target in data:
        optimizer.zero_grad()

        # 利用with语句,在autocast实例的上下文范围内,进行模型的前向推理和loss计算
        with autocast():
            output = model(input)
            loss = loss_fn(output, target)

        # 对loss进行缩放,针对缩放后的loss进行反向传播
        # (此部分计算在autocast()作用范围以外)
        scaler.scale(loss).backward()

        # 将梯度值缩放回原尺度后,优化器进行一步优化
        scaler.step(optimizer)

        # 更新scalar的缩放信息
        scaler.update()

3. Working with Unscaled Gradients

待更新

4. Working with Scaled Gradients

待更新

5. Working with Multiple Models, Losses, and Optimizers

如果模型的Loss计算部分输出多个loss,需要对每一个loss值执行scaler.scale

如果网络具有多个优化器,对任一个优化器执行scaler.unscale_,并对每一个优化器执行scaler.step

scaler.update只在最后执行一次。

应用示例如下:

scaler = torch.cuda.amp.GradScaler()

for epoch in epochs:
    for input, target in data:
        optimizer0.zero_grad()
        optimizer1.zero_grad()
        with autocast():
            output0 = model0(input)
            output1 = model1(input)
            loss0 = loss_fn(2 * output0 + 3 * output1, target)
            loss1 = loss_fn(3 * output0 - 5 * output1, target)

        scaler.scale(loss0).backward(retain_graph=True)
        scaler.scale(loss1).backward()

        # 选择其中一个优化器执行显式的unscaling
        scaler.unscale_(optimizer0)
		# 对每一个优化器执行scaler.step
        scaler.step(optimizer0)
        scaler.step(optimizer1)
		# 完成所有梯度更新后,执行一次scaler.update
        scaler.update()

6. Working with Multiple GPUs

针对多卡训练的情况,只影响autocast的使用方法,GradScaler的用法与之前一致。

6.1 DataParallel in a single process

在每一个不同的cuda设备上,torch.nn.DataParallel在不同的进程中执行前向推理,而autocast只在当前进程中生效,因此,如下方式的调用是不生效的:

model = MyModel()
dp_model = nn.DataParallel(model)

# 在主进程中设置autocast
with autocast():
    # dp_model的内部进程并不会对autocast生效
    output = dp_model(input)
    # loss的计算在主进程中执行,autocast可以生效,但由于前面执行推理时已经失效,因此整体上是不正确的
    loss = loss_fn(output)

有效的调用方式如下所示:

# 方法1:在模型构建中,定义forwar函数时,采用装饰器方式
MyModel(nn.Module):
    ...
    @autocast()
    def forward(self, input):
       ...

# 方法2:在模型构建中,定义forwar函数时,采用上下文管理器方式
MyModel(nn.Module):
    ...
    def forward(self, input):
        with autocast():
            ...

# DataParallel的使用方式不变
model = MyModel().cuda()
dp_model = nn.DataParallel(model)

# 在模型执行推理时,由于前面模型定义时的修改,在各cuda设备上的子进程中autocast生效
# 在执行loss计算是,在主进程中,autocast生效
with autocast():
    output = dp_model(input)
    loss = loss_fn(output)

6.2 DistributedDataParallel, one GPU per process

torch.nn.parallel.DistributedDataParallel在官方文档中推荐每个GPU执行一个实例的方法,以达到最好的性能表现。

在这种模式下,DistributedDataParallel内部并不会再启动子进程,因此对于autocastGradScaler的使用都没有影响,与典型示例保持一致。

6.3 DistributedDataParallel, multiple GPUs per process

DataParallel 的使用相同,在模型构建时,对forward函数的定义方式进行修改,保证autocast在进程内部生效。

免责声明:文章转载自《Pytorch原生AMP支持使用方法(1.6版本)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇接口测试中抓包工具的使用EasyDSS高性能流媒体服务器前端重构(六)- webpack-dev-server 支持手机端访问下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

如何获取显示器的EDID信息

可以说,作为一家以“显示”为生的企业,我们时时刻刻在与EDID打交道。“显示器你好,收到你的信息,现在就按最佳分辨率给你输出”。在输入端PC通过读取设备上的EDID来获悉设备支持的显示时序,而同样,在输出端设备需要读取显示器的EDID来确定自己的输出时序。液晶显示器、型号较新的CRT显示器和投影机在VGA接口都是有EDID的,而型号较老的CRT显示器和投影机...

influxdb简单使用

之前对influxdb有一个简单的了解和入门的使用,近期由于想使用influxdb做一点东西玩玩,又要捡起influxdb。而在influxdb下没有细分的表的概念,influxdb下的表在插入数据库的时候自动会创建。更多用户权限设置可以参看官方文档:https://docs.influxdata.com/influxdb/v1.0/query_langua...

硬中断与软中断的区别!

在多核系统上,一个中断通常只能中断一个CPU(也有一种特殊情况,即主机上有一个硬件通道。它可以在没有主CPU支持的情况下同时处理多个中断。软中断:1。软中断与硬中断非常相似。生成软中断的进程必须是当前正在运行的进程,因此它们不会中断CPU。...

带EFI支持的GRUB2安装全记录

--引导目录#定义引导目录。默认前缀是/boot/grub2,因此我们可以直接定义/。但是,如果您将其安装在EFI系统上,则可以直接写入EFI的装载点=====2016-02-26===============在新版本的grub2中找不到引导目录参数。特别是,在安装EFI时,需要将其更改为--EFI目录,否则您将找不到EFI目录的错误。grub2-insta...

Virtualbox虚拟机的显卡驱动和USB设备

如何在VirtualBox虚拟机的XP中安装图形卡驱动程序如何使VirtualBox中的Windows系统找到USB设备,并且无法为虚拟机envWINEPREFIX=“/home/cbx/.wine”wineC:Windows命令start.exe/Unix/home/cbx/打开新任务。wine/dos设备/c:/users/Public/桌面/QQ音乐l...

等保2.0 二级安全要求

1.6.2管理体系本要求包括:a)针对安全管理活动的主要管理内容建立安全管理体系;b) 应为管理人员或操作员进行的日常管理操作制定操作程序。...