如何降低专用GPU内存使用并在CUDA和PyTorch中使用共享GPU内存

14

当我尝试使用huggingface模型进行情感分析时,出现了以下错误:

RuntimeError: CUDA out of memory. Tried to allocate 72.00 MiB (GPU 0; 3.00 GiB total capacity; 1.84 GiB already allocated; 5.45 MiB free; 2.04 GiB reserved in total by PyTorch)

虽然我没有使用CUDA内存,但它仍然保持在同一水平。

enter image description here

我尝试使用torch.cuda.empty_cache(),但它没有影响到问题。 当我关闭jupyter笔记本时,内存使用量下降到0。因此,我非常确定这是与pytorch和python有关的问题。

以下是我的代码:

import joblib
import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification,pipeline
import torch.nn.functional as F
from torch.utils.data import DataLoader
import pandas as pd
import numpy as np
from tqdm import tqdm

tokenizer = AutoTokenizer.from_pretrained("savasy/bert-base-turkish-sentiment-cased")
model = AutoModelForSequenceClassification.from_pretrained("savasy/bert-base-turkish-sentiment-cased")

sa= pipeline("sentiment-analysis", tokenizer=tokenizer, model=model,device=0)
batcher = DataLoader(dataset=comments,
                      batch_size=100,
                      shuffle=True,
                      pin_memory=True)
predictions= []
for batch in tqdm(batcher):
     p = sa(batch)
     predictions.append(p)

我有一块GTX 1060显卡,安装了Python 3.8和torch==1.7.1,我的操作系统是Windows 10。评论计数为187K。我想知道是否有任何解决这个内存问题的方法。也许可以通过将张量保留在CPU上并仅在GPU上使用批处理来解决。在使用并出现此错误后,内存使用仍然持续增加。当我关闭jupyter笔记本时,它就消失了。有没有办法清除这个内存?有没有办法利用共享GPU内存?

2
你的批次大小对于你的GPU和像BERT这样的transformer来说太大了。试着使用批次大小为8,并从那里逐渐增加,如果可能的话。此外,令牌序列长度对内存使用有很大影响。 - John Stud
3
你也可以尝试使用PyTorch的自动混合精度库。由于你的GPU没有张量核心,所以速度不会更快,但它将使用更少的内存。链接 - Dwight Foster
3个回答

1
简短回答:你无法减少专用GPU内存的使用并使用共享GPU内存进行CUDA和Pytorch。
详细信息:我相信这个答案涵盖了你所需的所有信息。
你可以通过降低批量大小(如@John Stud所评论的)或使用自动混合精度(如@Dwight Foster建议的)来减少内存使用量。
在训练过程中,你可以实施梯度累积来减少批量大小而不影响性能。

0
简短回答:不行。
我确实遇到过这个问题,但是出于选择。我想要检查我的GPU在训练时的最大容量。首先要做的事情是:
- 检查是否在启动新的训练之前重新启动了内核。除非明确删除,复制的项目会保留在GPU内存中。只有在重新启动内核或明确清除时,它们才会被清理掉。
接下来是检查清单:
- 学习率。较小的学习率会使用更多的内存。0.0001 > 0.01。 - 批量大小。大批量大小和低学习率 = 更多的内存消耗。
优化:
你的内存很少,即3GB。共享内存在这里不适用,因为它是自动管理的。要在GPU上进行训练,你的张量必须在GPU内存中,而共享内存是系统内存。
你可以调整的数字通常是“批量大小”,在你的情况下是100,如果内存不足,你必须减小它。从8开始尝试,然后尝试16、32等等。使用偶数。你可以进行一个epoch的短期训练来测试。
增大学习率或使用Step LR来自动优化学习率。https://pytorch.org/docs/stable/generated/torch.optim.lr_scheduler.StepLR.html 我发现使用更多的内存并不意味着训练会更快完成。最终取决于超参数和CUDA核心的速度。
推理
由于你只用于预测,你也可以尝试使用CPU进行推理,并使用系统内存。你可以像这样使用数据加载器。
torch.utils.data.DataLoader(dataset=comments, \
                                           batch_size=batch_size, \
                                           shuffle=True \
                                           num_workers=num_workers)
# where num_workers is defined like this
import multiprocessing
num_workers = multiprocessing.cpu_count()

参考文献

https://superuser.com/questions/1416540/what-is-shared-gpu-memory-and-how-is-total-gpu-memory-calculated-windows-10

从pytorch论坛上的“共享内存”中,查看具体回复。 https://discuss.pytorch.org/t/what-is-the-shared-memory/112212/8

为什么你认为较小的学习率会使用更多的内存? - CuCaRot

-1
你不能这样做。 共享GPU(通常不是NVIDIA的)与独立GPU不同。CUDA只适用于来自NVIDIA的GPU。
然而,你可以尝试使用DirectML(适用于英特尔共享GPU),它可以帮助你在共享GPU上工作,而不是独立GPU。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接