关于pytorch指定了gpu还是占用了别的gpu的显存的问题

问题如下:

**
今天搭了一个服务,用到了多个模型,我的4块显卡显存都是12G的,而所有的模型运行起来一共占用9G,所以制定了所有的模型运行环境都是 cuda:0 ,然而在运行的时候,总会有一块别的GPU被莫名占用。找了半天找到问题,记录一哈
**

1、onnx服务选择gpu

我的服务中用到了多个模型,有的是转成了onnx的,有的就是pth的,转换失败了。
一开始我以为是某个onnx模型没有指定,所以莫名加载到了别的gpu上,所以在我所有的onnx运行时中都加上了gpu指定。

代码如下:

import onnxruntime as ort
self.encoder = ort.InferenceSession(encoder_path,providers=['CUDAExecutionProvider'])
self.encoder.set_providers(['CUDAExecutionProvider'], [ {'device_id': 0}])
self.encoder_input_name = self.encoder.get_inputs()[0].name
features = self.encoder.run(None,{self.encoder_input_name:img})[0]

这里 device_id : 0 指的是第一块gpu

测试结果确实可以指定gpu,但是那个莫名占用的gpu显存的情况还是存在,看来是torch的模型的问题

2、torch 选择gpu

class Provincer():
    def __init__(self,module_path=r'checkpoint/epoch_100.pth',device='cuda:0'):
        self.device = torch.device(device)

        self.net = resnet18()
        self.net.load_state_dict(torch.load(module_path))
        self.net.to(device)
        self.net.eval()

一顿debug,终于,在province模型调用的时候发现占用。具体的是在torch.load 时第三块gpu显存开始占用。

原因不知道,个人认为,应该时训练的时候放在了第三块gpu上,所以默认加载会放到那里,然后再复制到我指定的gpu上。
所以这里修改一下默认加载位置为cpu。

class Provincer():
    def __init__(self,module_path=r'checkpoint/epoch_100.pth',device='cuda:0'):
        self.device = torch.device(device)

        self.net = resnet18()
        self.net.load_state_dict(torch.load(module_path,map_location='cpu'))
        self.net.to(device)
        self.net.eval()

重新加载,ok,果然可以了。

3、运行时设置

当然,这里还有个比较好的解决方法,运行时设置使用的gpu设备

如开始运行命令为

python3 server.py

可以修改为

CUDA_VISIBLE_DEVICES=1 python3 server.py

或者在代码中增加

import os
os.environ['CUDA_VISIBLE_DEVICES'] = '1'

然后在搜索时发现有人提供了一种方法

将所有的加载代码放在with中,此方法没有尝试,先记录下来。

with torch.cuda.device(1):
	pass
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
PyTorch支持使用多张显卡进行并行训练,可以使用`torch.nn.DataParallel`或`torch.nn.parallel.DistributedDataParallel`来实现。以下是使用`torch.nn.DataParallel`的示例代码: ```python import torch import torch.nn as nn from torch.utils.data import DataLoader # 定义模型 class MyModel(nn.Module): def __init__(self): super(MyModel, self).__init__() self.fc1 = nn.Linear(10, 5) self.fc2 = nn.Linear(5, 1) def forward(self, x): x = self.fc1(x) x = torch.relu(x) x = self.fc2(x) return x # 定义数据集 class MyDataset(torch.utils.data.Dataset): def __init__(self): self.data = torch.randn(100, 10) self.targets = torch.randn(100, 1) def __getitem__(self, index): return self.data[index], self.targets[index] def __len__(self): return len(self.data) # 定义训练函数 def train(model, dataloader, optimizer, criterion): model.train() for i, (inputs, targets) in enumerate(dataloader): optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, targets) loss.backward() optimizer.step() # 创建模型、数据集、数据加载器、优化器、损失函数 model = MyModel() dataset = MyDataset() dataloader = DataLoader(dataset, batch_size=8, shuffle=True) optimizer = torch.optim.SGD(model.parameters(), lr=0.01) criterion = nn.MSELoss() # 使用DataParallel进行多GPU并行训练 model = nn.DataParallel(model) device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") model.to(device) for epoch in range(10): train(model, dataloader, optimizer, criterion) ``` 在上面的代码中,我们首先定义了一个模型`MyModel`和一个数据集`MyDataset`。然后,我们使用`DataLoader`将数据集加载到内存中。接下来,我们创建了一个优化器和一个损失函数。最后,我们将模型移到GPU上,并使用`DataParallel`对其进行并行处理。在训练循环中,我们调用`train`函数来训练模型。`train`函数的参数分别是模型、数据加载器、优化器和损失函数。由于我们在模型上调用了`DataParallel`,因此在训练循环中,我们不需要手动处理多个GPU的并行计算。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值