- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
对于我的优化算法,每次迭代我都需要评估几百张图像。为了加快这个过程,我想充分利用我的 3 个 GPU。
我的过程:
现在执行一次并结束问题没有问题,但是,当我重复执行此操作时,GPU 内存开始填满每次迭代,直到出现“RuntimeError:CUDA 错误:内存不足”
我的问题:
更新考虑到此 thread 中出现的问题,我重新编写了代码.在程序的任何循环之外实例化 Pool() 并没有解决 GPU 内存溢出问题,但是,它阻止了 CPU 内存随着时间的推移而增加。
'''
Test GPU Memory Leak
Description: Tests how the memory doesn't get freed up when running multiprocessing with PyTorch Model forward pass
'''
import torch
import torch.multiprocessing as mp
import importlib
from PIL import Image
from skimage import io, transform
from skimage.color import rgb2gray
from skimage.io._plugins.pil_plugin import *
import torch
import torch.nn as nn
# Convolutional neural network (twohttps://duckduckgo.com/?q=install+gmsh+conda&t=canonical convolutional layers)
class ConvNet(nn.Module):
def __init__(self, num_classes=10, num_img_layers = 1, img_res = 128):
super(ConvNet, self).__init__()
self.layer1 = nn.Sequential(
#torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1,
# padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros')
nn.Conv2d(num_img_layers, 64, kernel_size=5, stride=1, padding=2),
nn.BatchNorm2d(64),
nn.LeakyReLU())
self.layer2 = nn.Sequential(
nn.Conv2d(64, 32, kernel_size=5, stride=1, padding=2),
nn.BatchNorm2d(32),
nn.LeakyReLU(),
nn.MaxPool2d(kernel_size=2, stride=2))
self.fc1 = nn.Linear(32*int(img_res/2)*int(img_res/2), 32*32)
self.fc2 = nn.Linear(32*32, num_classes)
def forward(self, x):
#print(x.shape)
out = self.layer1(x)
#print(out.shape)
out = self.layer2(out)
#print(out.shape)
out = out.reshape(out.size(0), -1)
out = self.fc1(out)
out = self.fc2(out)
return out
class NNEvaluator:
def __init__(self, model_dict, GPU, img_res = 128, num_img_layers = 1, num_classes = None):
# Load the model checkpoint
gpu_id = 'cuda:' + str(GPU)
self.device = torch.device(gpu_id if torch.cuda.is_available() else 'cpu')
self.model_state_dict = model_dict['model_state_dict']
self.model = ConvNet(num_classes = num_classes, num_img_layers = num_img_layers, img_res = img_res).to(self.device)
self.model.to(self.device)
self.model.load_state_dict(self.model_state_dict)
self.epsilon = torch.tensor(1e-12, dtype = torch.float)
def evaluate(self, img):
self.model.eval()
with torch.no_grad():
img = img.to(self.device)
out = self.model(img)
out = out.to('cpu')
return out
def loadImage(filename):
im = Image.open("test.jpg")
im = io._plugins.pil_plugin.pil_to_ndarray(im)
im = rgb2gray(im)
image = im.transpose((0, 1))
im = torch.from_numpy(image).float()
im = torch.unsqueeze(im,0)
im = torch.unsqueeze(im,1)
return im
def _worker(workload, evaluator):
results = []
for img in workload:
results.append(evaluator.evaluate(img))
def main():
# load a model for each GPU
model_dict = torch.load('model_dict.ckpt')
GPUs = [0,1,2] # available GPUs in the system
evaluators = []
for gpu_id in GPUs:
evaluators.append(NNEvaluator(model_dict, gpu_id, num_classes=3))
# instantiate multiprocessing pool
mp.set_start_method('spawn')
mypool = mp.Pool()
# evaluate all datapoints 20 times
im = loadImage('test.jpg')
total_nr_iterations = 20
for i in range(total_nr_iterations):
# run a subset of the workload on each GPU in a separate process
nr_datapoints = 99
dp_per_evaluator = int(nr_datapoints/len(evaluators))
workload = [im for i in range(dp_per_evaluator)]
jobslist = [(workload, evaluator) for evaluator in evaluators]
mypool.starmap(_worker, jobslist)
print("Finished iteration {}".format(i))
if __name__ == '__main__':
main()
运行代码时的输出:
Finished iteration 0
Finished iteration 1
Finished iteration 2
Process SpawnPoolWorker-10:
Process SpawnPoolWorker-12:
Traceback (most recent call last):
Traceback (most recent call last):
File "/home/ron/miniconda3/envs/PyTorchNN/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
self.run()
File "/home/ron/miniconda3/envs/PyTorchNN/lib/python3.7/multiprocessing/process.py", line 99, in run
self._target(*self._args, **self._kwargs)
File "/home/ron/miniconda3/envs/PyTorchNN/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
self.run()
File "/home/ron/miniconda3/envs/PyTorchNN/lib/python3.7/multiprocessing/pool.py", line 110, in worker
task = get()
File "/home/ron/miniconda3/envs/PyTorchNN/lib/python3.7/multiprocessing/process.py", line 99, in run
self._target(*self._args, **self._kwargs)
File "/home/ron/miniconda3/envs/PyTorchNN/lib/python3.7/multiprocessing/queues.py", line 354, in get
return _ForkingPickler.loads(res)
File "/home/ron/miniconda3/envs/PyTorchNN/lib/python3.7/multiprocessing/pool.py", line 110, in worker
task = get()
File "/home/ron/miniconda3/envs/PyTorchNN/lib/python3.7/site-packages/torch/multiprocessing/reductions.py", line 119, in rebuild_cuda_tensor
event_sync_required)
File "/home/ron/miniconda3/envs/PyTorchNN/lib/python3.7/multiprocessing/queues.py", line 354, in get
return _ForkingPickler.loads(res)
File "/home/ron/miniconda3/envs/PyTorchNN/lib/python3.7/site-packages/torch/multiprocessing/reductions.py", line 119, in rebuild_cuda_tensor
event_sync_required)
RuntimeError: CUDA error: out of memory
RuntimeError: CUDA error: out of memory
Process SpawnPoolWorker-11:
Traceback (most recent call last):
File "/home/ron/miniconda3/envs/PyTorchNN/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
self.run()
File "/home/ron/miniconda3/envs/PyTorchNN/lib/python3.7/multiprocessing/process.py", line 99, in run
self._target(*self._args, **self._kwargs)
File "/home/ron/miniconda3/envs/PyTorchNN/lib/python3.7/multiprocessing/pool.py", line 110, in worker
task = get()
File "/home/ron/miniconda3/envs/PyTorchNN/lib/python3.7/multiprocessing/queues.py", line 354, in get
return _ForkingPickler.loads(res)
File "/home/ron/miniconda3/envs/PyTorchNN/lib/python3.7/site-packages/torch/multiprocessing/reductions.py", line 119, in rebuild_cuda_tensor
event_sync_required)
RuntimeError: CUDA error: out of memory
最佳答案
我发现这个类似 thread由于 Pool() 在循环中而不是在外部的实例化而发生内存泄漏。
上述问题还在函数内部实例化了 Pool() 而没有使用 with
符号,这将确保所有启动的进程都返回
例如坏方法:
def evaluation(workload):
jobslist = [job for job in workload]
with Pool() as mypool:
mypool.starmap(_workerfunction, jobslist)
if __name__ == '__main__':
# pseudo data
workload = [[(100,200) for i in range(1000)] for i in range(50)]
for i in range(100):
evaluation(workload)
这样做的正确方法是在循环外实例化池,并将对池的引用传递给函数进行处理,即:
def evaluation(workload, mypool):
jobslist = [job for job in workload]
mypool.starmap(_workerfunction, jobslist)
if __name__ == '__main__':
# pseudo data
with Pool() as mypool:
workload = [[(100,200) for i in range(1000)] for i in range(50)]
for i in range(100):
evaluation(workload, mypool)
我怀疑 GPU 内存泄漏是由于并行进程中尚未清理的遗留引用造成的。
关于python-3.x - 在并行过程中评估 PyTorch 模型上的数据后,GPU 内存不会被释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59395680/
有没有办法同时运行 2 个不同的代码块。我一直在研究 R 中的并行包,它们似乎都基于在循环中运行相同的函数。我正在寻找一种同时运行不同函数的方法(循环的 1 次迭代)。例如,我想在某个数据对象上创建一
无论如何增加 Parallel.For 启动后的循环次数?示例如下: var start = 0; var end = 5; Parallel.For(start, end, i => { C
我是 Golang 的新手,正在尝试了解并发和并行。我阅读了下面提到的关于并发和并行的文章。我执行了相同的程序。但没有得到相同的(混合字母和字符)输出。首先获取所有字母,然后获取字符。似乎并发不工作,
我正在寻找同时迭代 R 中两个或多个字符向量/列表的方法,例如。有没有办法做这样的事情: foo <- c('a','c','d') bar <- c('aa','cc','dd') for(i in
我对 Raku 很陌生,我对函数式方法有疑问,尤其是 reduce。 我最初有这样的方法: sub standardab{ my $mittel = mittel(@_); my $foo =
我最近花了很多时间来学习实时音频处理的细节,我发现的大多数库/工具都是c / c++代码或脚本/图形语言的形式,并在其中编译了c / c++代码。引擎盖。 使用基于回调的API,与GUI或App中的其
我正在使用 JMeter 进行图像负载测试。我有一个图像名称数组并遍历该数组,我通过 HTTP 请求获取所有图像。 -> loop_over_image - for loop controller
我整个晚上都在困惑这个问题...... makeflags = ['--prefix=/usr','--libdir=/usr/lib'] rootdir='/tmp/project' ps = se
我正在尝试提高计算图像平均值的方法的性能。 为此,我使用了两个 For 语句来迭代所有图像,因此我尝试使用一个 Parallel For 来改进它,但结果并不相同。 我做错了吗?或者是什么导致了差异?
假设您有一个并行 for 循环实现,例如ConcRT parallel_for,将所有工作放在一个 for 循环体内总是最好的吗? 举个例子: for(size_t i = 0; i < size()
我想并行运行一部分代码。目前我正在使用 Parallel.For 如何让10、20或40个线程同时运行 我当前的代码是: Parallel.For(1, total, (ii) =>
我使用 PAY API 进行了 PayPal 自适应并行支付,其中无论用户(买家)购买什么,都假设用户购买了总计 100 美元的商品。在我的自适应并行支付中,有 2 个接收方:Receiver1 和
我正在考虑让玩家加入游戏的高效算法。由于会有大量玩家,因此算法应该是异步的(即可扩展到集群中任意数量的机器)。有细节:想象有一个无向图(每个节点都是一个玩家)。玩家之间的每条边意味着玩家可以参加同一场
我有一个全局变量 volatile i = 0; 和两个线程。每个都执行以下操作: i++; System.out.print(i); 我收到以下组合。 12、21 和 22。 我理解为什么我没有得到
我有以下称为 pgain 的方法,它调用我试图并行化的方法 dist: /***************************************************************
我有一个 ruby 脚本读取一个巨大的表(约 2000 万行),进行一些处理并将其提供给 Solr 用于索引目的。这一直是我们流程中的一大瓶颈。我打算在这里加快速度,我想实现某种并行性。我对 Ru
我正在研究 Golang 并遇到一个问题,我已经研究了几天,我似乎无法理解 go routines 的概念以及它们的使用方式。 基本上我是在尝试生成数百万条随机记录。我有生成随机数据的函数,并将创建一
我希望 for 循环使用 go 例程并行。我尝试使用 channel ,但没有用。我的主要问题是,我想在继续之前等待所有迭代完成。这就是为什么在它不起作用之前简单地编写 go 的原因。我尝试使用 ch
我正在使用 import Control.Concurrent.ParallelIO.Global main = parallel_ (map processI [1..(sdNumber runPa
我正在尝试通过 makePSOCKcluster 连接到另一台计算机: library(parallel) cl ... doTryCatch -> recvData -> makeSOCKm
我是一名优秀的程序员,十分优秀!