本指南从最简单的结构到最复杂的改动都有,可以使你的网络得到最大的好处。我会给你展示示例Pytorch代码以及可以在Pytorch- lightning Trainer中使用的相关flags,这样你可以不用自己编写这些代码!

 9个技巧让你的PyTorch模型练习变得飞快!(pytorch模型训练最新实用教程) PyTorch 神经网络 代码 第1张

不要让你的神经网络变成这样

让咱们面对现实吧,你的模型或许还停留在石器年代。我敢打赌你依然运用32位精度或GASP乃至只在一个GPU上练习。

我理解,网上都是各种神经网络加快攻略,可是一个checklist都没有(现在有了),运用这个清单,一步一步保证你能榨干你模型的一切功用。

本攻略从最简略的结构到最杂乱的改动都有,能够使你的网络得到最大的优点。我会给你展现示例Pytorch代码以及能够在Pytorch- lightning Trainer中运用的相关flags,这样你能够不必自己编写这些代码!

**这本攻略是为谁预备的?**任何运用Pytorch进行深度学习模型研讨的人,如研讨人员、博士生、学者等,咱们在这里议论的模型或许需求你花费几天的练习,乃至是几周或几个月。

咱们会讲到:

  • 运用DataLoaders
  • DataLoader中的workers数量
  • Batch size
  • 梯度累计
  • 保存的核算图
  • 移动到单个
  • 16-bit 混合精度练习
  • 移动到多个GPUs中(模型仿制)
  • 移动到多个GPU-nodes中 (8+GPUs)
  • 考虑模型加快的技巧

Pytorch-Lightning

 9个技巧让你的PyTorch模型练习变得飞快!(pytorch模型训练最新实用教程) PyTorch 神经网络 代码 第2张

你能够在Pytorch的库Pytorch- lightning中找到我在这里评论的每一个优化。Lightning是在Pytorch之上的一个封装,它能够主动练习,徘徊让研讨人员彻底操控要害的模型组件。Lightning 运用最新的最佳实践,并将你或许犯错的当地最小化。

咱们为MNIST界说LightningModel并运用Trainer来练习模型。

  1. frompytorch_lightningimportTrainer
  2. model=LightningModule(…)
  3. trainer=Trainer()
  4. trainer.fit(model)

1. DataLoaders

 9个技巧让你的PyTorch模型练习变得飞快!(pytorch模型训练最新实用教程) PyTorch 神经网络 代码 第3张

这或许是最简略取得速度增益的当地。保存h5py或numpy文件以加快数据加载的年代现已一去不复返了,运用Pytorch dataloader加载图画数据很简略(关于NLP数据,请检查TorchText)。

在lightning中,你不需求指定练习循环,只需求界说dataLoaders和Trainer就会在需求的时分调用它们。

  1. dataset=MNIST(root=self.hparams.data_root,traintrain=train,download=True)
  2. loader=DataLoader(dataset,batch_size=32,shuffle=True)
  3. forbatchinloader:
  4. x,y=batch
  5. model.training_step(x,y)
  6. ...

2. DataLoaders 中的 workers 的数量

 9个技巧让你的PyTorch模型练习变得飞快!(pytorch模型训练最新实用教程) PyTorch 神经网络 代码 第4张

另一个加快的奇特之处是答应批量并行加载。因而,您能够一次装载nb_workers个batch,而不是一次装载一个batch。

  1. #slow
  2. loader=DataLoader(dataset,batch_size=32,shuffle=True)
  3. #fast(use10workers)
  4. loader=DataLoader(dataset,batch_size=32,shuffle=True,num_workers=10)

3. Batch size

 9个技巧让你的PyTorch模型练习变得飞快!(pytorch模型训练最新实用教程) PyTorch 神经网络 代码 第5张

在开端下一个优化过程之前,将batch size增大到CPU-RAM或GPU-RAM所答应的最大规模。

下一节将要点介绍怎么协助削减内存占用,以便你能够持续添加batch size。

记住,你或许需求再次更新你的学习率。一个好的经历法则是,假如batch size加倍,那么学习率就加倍。

4. 梯度累加

 9个技巧让你的PyTorch模型练习变得飞快!(pytorch模型训练最新实用教程) PyTorch 神经网络 代码 第6张

在你现已到达核算资源上限的情况下,你的batch size依然太小(比方8),然后咱们需求模仿一个更大的batch size来进行梯度下降,以供给一个杰出的估量。

假定咱们想要到达128的batch size巨细。咱们需求以batch size为8履行16个前向传达和向后传达,然后再履行一次优化过程。

  1. #clearlaststep
  2. optimizer.zero_grad()
  3. #16accumulatedgradientsteps
  4. scaled_loss=0
  5. foraccumulated_step_iinrange(16):
  6. out=model.forward()
  7. loss=some_loss(out,y)
  8. loss.backward()
  9. scaled_loss+=loss.item()
  10. #updateweightsafter8steps.effectivebatch=8*16
  11. optimizer.step()
  12. #lossisnowscaledupbythenumberofaccumulatedbatches
  13. actual_loss=scaled_loss/16

在lightning中,全部都给你做好了,只需求设置accumulate_grad_batches=16:

  1. trainer=Trainer(accumulate_grad_batches=16)
  2. trainer.fit(model)

5. 保存的核算图

 9个技巧让你的PyTorch模型练习变得飞快!(pytorch模型训练最新实用教程) PyTorch 神经网络 代码 第7张

一个最简略撑爆你的内存的办法是为了记载日志存储你的loss。

  1. losses=[]
  2. ...
  3. losses.append(loss)
  4. print(f'currentloss:{torch.mean(losses)'})

上面的问题是,loss依然包括有整个图的副本。在这种情况下,调用.item()来开释它。

  1. ![1_CER3v8cok2UOBNsmnBrzPQ](9TipsForTrainingLightning-FastNeuralNetworksInPytorch.assets/1_CER3v8cok2UOBNsmnBrzPQ.gif)#bad
  2. losses.append(loss)
  3. #good
  4. losses.append(loss.item())

Lightning会十分当心,保证不会保存核算图的副本。

6. 单个GPU练习

 9个技巧让你的PyTorch模型练习变得飞快!(pytorch模型训练最新实用教程) PyTorch 神经网络 代码 第8张

一旦你现已完成了前面的过程,是时分进入GPU练习了。在GPU上的练习将使多个GPU cores之间的数学核算并行化。你得到的加快取决于你所运用的GPU类型。我引荐个人用2080Ti,公司用V100。

乍一看,这或许会让你手足无措,但你真的只需求做两件事:1)移动你的模型到GPU, 2)每逢你运转数据经过它,把数据放到GPU上。

  1. #putmodelonGPU
  2. model.cuda(0)
  3. #putdataongpu(cudaonavariablereturnsacudacopy)
  4. xx=x.cuda(0)
  5. #runsonGPUnow
  6. model(x)

假如你运用Lightning,你什么都不必做,只需求设置Trainer(gpus=1)。

  1. #asklightningtousegpu0fortraining
  2. trainer=Trainer(gpus=[0])
  3. trainer.fit(model)

在GPU上进行练习时,要留意的首要作业是约束CPU和GPU之间的传输次数。

  1. #expensive
  2. xx=x.cuda(0)#veryexpensive
  3. xx=x.cpu()
  4. xx=x.cuda(0)

假如内存耗尽,不要将数据移回CPU以节约内存。在求助于GPU之前,测验以其他方法优化你的代码或GPU之间的内存散布。

另一件需求留意的作业是调用强制GPU同步的操作。铲除内存缓存便是一个比如。

  1. dataset=MNIST(root=self.hparams.data_root,traintrain=train,download=True)
  2. loader=DataLoader(dataset,batch_size=32,shuffle=True)
  3. forbatchinloader:
  4. x,y=batch
  5. model.training_step(x,y)
  6. ...
0

可是,假如运用Lightning,专一或许出现问题的当地是在界说Lightning Module时。Lightning会特别留意不去犯这类过错。

7. 16-bit 精度

16bit精度是将内存占用折半的惊人技能。大多数模型运用32bit精度数字进行练习。可是,最近的研讨发现,16bit模型也能够作业得很好。混合精度意味着对某些内容运用16bit,但将权重等内容保持在32bit。

要在Pytorch中运用16bit精度,请装置NVIDIA的apex库,并对你的模型进行这些更改。

  1. dataset=MNIST(root=self.hparams.data_root,traintrain=train,download=True)
  2. loader=DataLoader(dataset,batch_size=32,shuffle=True)
  3. forbatchinloader:
  4. x,y=batch
  5. model.training_step(x,y)
  6. ...
1

amp包会处理好大部分作业。假如梯度爆破或趋向于0,它乃至会缩放loss。

在lightning中,启用16bit并不需求修正模型中的任何内容,也不需求履行我上面所写的操作。设置Trainer(precision=16)就能够了。

  1. dataset=MNIST(root=self.hparams.data_root,traintrain=train,download=True)
  2. loader=DataLoader(dataset,batch_size=32,shuffle=True)
  3. forbatchinloader:
  4. x,y=batch
  5. model.training_step(x,y)
  6. ...
2

8. 移动到多个GPUs中

现在,作业变得十分风趣了。有3种(或许更多?)办法来进行多GPU练习。

分batch练习

 9个技巧让你的PyTorch模型练习变得飞快!(pytorch模型训练最新实用教程) PyTorch 神经网络 代码 第9张

A) 仿制模型到每个GPU中,B) 给每个GPU一部分batch

榜首种办法被称为“分batch练习”。该战略将模型仿制到每个GPU上,每个GPU取得batch的一部分。

  1. dataset=MNIST(root=self.hparams.data_root,traintrain=train,download=True)
  2. loader=DataLoader(dataset,batch_size=32,shuffle=True)
  3. forbatchinloader:
  4. x,y=batch
  5. model.training_step(x,y)
  6. ...
3

在lightning中,你只需求添加GPUs的数量,然后告知trainer,其他什么都不必做。

  1. dataset=MNIST(root=self.hparams.data_root,traintrain=train,download=True)
  2. loader=DataLoader(dataset,batch_size=32,shuffle=True)
  3. forbatchinloader:
  4. x,y=batch
  5. model.training_step(x,y)
  6. ...
4

模型散布练习

 9个技巧让你的PyTorch模型练习变得飞快!(pytorch模型训练最新实用教程) PyTorch 神经网络 代码 第10张

将模型的不同部分放在不同的GPU上,batch按次序移动

有时你的模型或许太大不能彻底放到内存中。例如,带有编码器和解码器的序列到序列模型在生成输出时或许会占用20GB RAM。在本例中,咱们期望将编码器和解码器放在独立的GPU上。

  1. dataset=MNIST(root=self.hparams.data_root,traintrain=train,download=True)
  2. loader=DataLoader(dataset,batch_size=32,shuffle=True)
  3. forbatchinloader:
  4. x,y=batch
  5. model.training_step(x,y)
  6. ...
5

关于这种类型的练习,在Lightning中不需求指定任何GPU,你应该把LightningModule中的模块放到正确的GPU上。

  1. dataset=MNIST(root=self.hparams.data_root,traintrain=train,download=True)
  2. loader=DataLoader(dataset,batch_size=32,shuffle=True)
  3. forbatchinloader:
  4. x,y=batch
  5. model.training_step(x,y)
  6. ...
6

两者混合

在上面的情况下,编码器和解码器依然能够从并行化操作中获益。

  1. dataset=MNIST(root=self.hparams.data_root,traintrain=train,download=True)
  2. loader=DataLoader(dataset,batch_size=32,shuffle=True)
  3. forbatchinloader:
  4. x,y=batch
  5. model.training_step(x,y)
  6. ...
7

运用多个GPU时要考虑的留意事项:

  • 假如模型现已在GPU上了,model.cuda()不会做任何作业。
  • 总是把输入放在设备列表中的榜首个设备上。
  • 在设备之间传输数据是贵重的,把它作为最终的手法。
  • 优化器和梯度会被保存在GPU 0上,因而,GPU 0上运用的内存或许会比其他GPU大得多

9. 多节点GPU练习

 9个技巧让你的PyTorch模型练习变得飞快!(pytorch模型训练最新实用教程) PyTorch 神经网络 代码 第11张

每台机器上的每个GPU都有一个模型的副本。每台机器取得数据的一部分,而且只在那部分上练习。每台机器都能同步梯度。

假如你现已做到了这一步,那么你现在能够在几分钟内练习Imagenet了!这并没有你幻想的那么难,可是它或许需求你对核算集群的更多常识。这些阐明假定你正在集群上运用SLURM。

Pytorch答应多节点练习,经过在每个节点上仿制每个GPU上的模型并同步梯度。所以,每个模型都是在每个GPU上独立初始化的,本质上独登时在数据的一个分区上练习,除了它们都从一切模型接纳梯度更新。

在高层次上:

  1. 在每个GPU上初始化一个模型的副本(保证设置种子,让每个模型初始化到相同的权重,不然它会失利)。
  2. 将数据集分割成子集(运用DistributedSampler)。每个GPU只在它自己的小子集上练习。
  3. 在.backward()上,一切副本都接纳到一切模型的梯度副本。这是模型之间仅有一次的通讯。

Pytorch有一个很好的笼统,叫做DistributedDataParallel,它能够帮你完成这个功用。要运用DDP,你需求做4的作业:

  1. dataset=MNIST(root=self.hparams.data_root,traintrain=train,download=True)
  2. loader=DataLoader(dataset,batch_size=32,shuffle=True)
  3. forbatchinloader:
  4. x,y=batch
  5. model.training_step(x,y)
  6. ...
8
转载请说明出处
知优网 » 9个技巧让你的PyTorch模型练习变得飞快!(pytorch模型训练最新实用教程)

发表评论

您需要后才能发表评论