遇到与CUDA相关的问题

遇到与CUDA相关的问题
在运行如下代码:

import os
import cv2
import torch,gc

import numpy as np
import albumentations as albu
import segmentation_models_pytorch as smp

from albumentations.pytorch import ToTensorV2
from albumentations import Compose
from numba.cuda.libdeviceimpl import args

from tqdm import tqdm

CONFIG = {
    'img_size': 608,
    'model_name': 'timm-efficientnet-b7',
    'ckpt': 'ty_608_best.pth.tar',
}

os.environ['CUDA_VISIBLE_DEVICES'] = "0"
# device = torch.device("cuda:0" if torch.cuda.is_available() and not args.no_cuda else "cpu")


def make_transforms(tta=False):
    list_transforms = []
    if tta:
        list_transforms.extend(
            [
                albu.HorizontalFlip(p=1),
            ]
        )
    list_transforms.extend(
        [
            albu.Resize(CONFIG['img_size'], CONFIG['img_size']),
            ToTensorV2(),
        ]
    )

    list_trfms = Compose(list_transforms)
    return list_trfms


model = smp.UnetPlusPlus(
    CONFIG['model_name'],
    classes=1,
    encoder_weights=None,
    activation=None,
).cuda()
stuff = torch.load(CONFIG['ckpt'])
model.load_state_dict(stuff['state_dict'])
model.eval()


def sigmoid(x):
    return 1 / (1 + np.exp(-x))


test_trans = make_transforms()
tta_trans = make_transforms(tta=True)


def crop_image(img, crop_w, crop_h):
    ori_size = img.shape[0:2]  # 原图尺寸 (height, width)
    row_num = int(ori_size[0] / crop_h) + 1
    column_num = int(ori_size[1] / crop_w) + 1

    new_height = row_num * crop_h  # 小图像尺寸整倍数的大图像
    new_width = column_num * crop_w

    pad_h = new_height - ori_size[0]  # 在高维度上需要填充的像素
    pad_w = new_width - ori_size[1]

    # 从右下方填充
    img_new = cv2.copyMakeBorder(img, 0, pad_h, 0, pad_w, cv2.BORDER_CONSTANT, None, (0, 0, 0))

    crop_list = []
    for i in range(row_num):
        for j in range(column_num):
            img_crop = img_new[i * crop_h: (i + 1) * crop_h, j * crop_w: (j + 1) * crop_w]
            crop_list.append(img_crop)
    return crop_list, row_num, column_num


def compose_crop(mask_list, crop_w, crop_h, row, column, ori_w, ori_h):
    new_width = crop_w * column
    new_height = crop_h * row

    to_image = np.zeros((new_height, new_width, 1))
    i = 0
    for j in range(row):
        for k in range(column):
            to_image[j * crop_h: (j + 1) * crop_h, k * crop_w: (k + 1) * crop_w] = mask_list[i]
            i += 1

    return to_image[0:ori_h, 0:ori_w]


# input_dir = 'test.png'
# output_dir = 'image_output'
# trans_type = 'compose'

# if not os.path.exists(output_dir):
#     os.makedirs(output_dir)
def seal_ps(images,trans_type):
    # for temp_img in tqdm(os.listdir('test.png')):
    #     print(temp_img)
    #     if temp_img == '.ipynb_checkpoints':
    #         continue
    #     img_path = os.path.join(input_dir, temp_img)
    img_ori = cv2.imread(images)
    ori_size = img_ori.shape[0:2]
    crop_list, row_num, column_num = crop_image(img_ori, CONFIG['img_size'], CONFIG['img_size'])

    mask_list = []

    for i, crop_item in enumerate(crop_list):
        # img_path = os.path.join('example/1', name)
        # image = cv2.imread(img_path)
        img_rgb = cv2.cvtColor(crop_item, cv2.COLOR_BGR2RGB)
        shape = img_rgb.shape
        augmented = test_trans(image=img_rgb)
        img = augmented['image']
        img = img.float()

        ttaa = tta_trans(image=img_rgb)
        image_tta = ttaa['image']
        image_tta = image_tta.float()

        mask1 = 0

        if trans_type == 'default':

            masks1 = model(img.unsqueeze(0).cuda())

            mask1 += albu.Resize(shape[0], shape[1])(image=masks1[0].permute(1, 2, 0).detach().cpu().numpy())['image']
        elif trans_type == 'tta':
            masks_tta1 = model(image_tta.unsqueeze(0).cuda())
            mask1 += \
                albu.Resize(shape[0], shape[1])(
                    image=np.flip(masks_tta1[0].permute(1, 2, 0).detach().cpu().numpy(), axis=1))[
                    'image']
        elif trans_type == 'compose':
            masks1 = model(img.unsqueeze(0).cuda())

            mask1 += albu.Resize(shape[0], shape[1])(image=masks1[0].permute(1, 2, 0).detach().cpu().numpy())['image']
            masks_tta1 = model(image_tta.unsqueeze(0).cuda())
            mask1 += \
                albu.Resize(shape[0], shape[1])(
                    image=np.flip(masks_tta1[0].permute(1, 2, 0).detach().cpu().numpy(), axis=1))[
                    'image']
            mask1 /= 2

        fake_mask = ((sigmoid(mask1) > 0.5) * 255.).astype(np.uint8)
        mask_list.append(fake_mask.astype(np.uint8))

    mask_image = compose_crop(mask_list, CONFIG['img_size'], CONFIG['img_size'], row_num, column_num, ori_size[1],
                              ori_size[0])

    mask_image = mask_image.squeeze()
    mask_image = mask_image.astype(np.uint8)

    contours, _ = cv2.findContours(mask_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cv2.drawContours(img_ori, contours, -1, (255, 0, 0), 1)

    # img_ori = img_ori[:, :, ::-1]
    # img_ori[..., 2] = np.where(mask_image == 1, 255, img_ori[..., 2])

    # cv2.imwrite(os.path.join(output_dir, temp_img), img_ori)
    gc.collect()
    torch.cuda.empty_cache()
if __name__ == '__main__':
    # pic = open("8.png", "rb")
    b = seal_ps('test.png',trans_type = 'compose')
    # b.show()

    # b = cv2.imread('8.png')

    print(b)

报错如下:

Traceback (most recent call last):
  File "D:\test11\印章ps\predict_images.py", line 174, in <module>
    b = seal_ps('test.png',trans_type = 'compose')
  File "D:\test11\印章ps\predict_images.py", line 147, in seal_ps
    masks_tta1 = model(image_tta.unsqueeze(0).cuda())
  File "D:\Anaconda3\envs\cj-env\lib\site-packages\torch\nn\modules\module.py", line 1194, in _call_impl
    return forward_call(*input, **kwargs)
  File "D:\Anaconda3\envs\cj-env\lib\site-packages\segmentation_models_pytorch\base\model.py", line 29, in forward
    features = self.encoder(x)
  File "D:\Anaconda3\envs\cj-env\lib\site-packages\torch\nn\modules\module.py", line 1194, in _call_impl
    return forward_call(*input, **kwargs)
  File "D:\Anaconda3\envs\cj-env\lib\site-packages\segmentation_models_pytorch\encoders\timm_efficientnet.py", line 120, in forward
    x = stages[i](x)
  File "D:\Anaconda3\envs\cj-env\lib\site-packages\torch\nn\modules\module.py", line 1194, in _call_impl
    return forward_call(*input, **kwargs)
  File "D:\Anaconda3\envs\cj-env\lib\site-packages\torch\nn\modules\container.py", line 204, in forward
    input = module(input)
  File "D:\Anaconda3\envs\cj-env\lib\site-packages\torch\nn\modules\module.py", line 1194, in _call_impl
    return forward_call(*input, **kwargs)
  File "D:\Anaconda3\envs\cj-env\lib\site-packages\torch\nn\modules\container.py", line 204, in forward
    input = module(input)
  File "D:\Anaconda3\envs\cj-env\lib\site-packages\torch\nn\modules\module.py", line 1194, in _call_impl
    return forward_call(*input, **kwargs)
  File "D:\Anaconda3\envs\cj-env\lib\site-packages\timm\models\efficientnet_blocks.py", line 182, in forward
    x = self.bn1(x)
  File "D:\Anaconda3\envs\cj-env\lib\site-packages\torch\nn\modules\module.py", line 1194, in _call_impl
    return forward_call(*input, **kwargs)
  File "D:\Anaconda3\envs\cj-env\lib\site-packages\timm\models\layers\norm_act.py", line 109, in forward
    self.eps,
  File "D:\Anaconda3\envs\cj-env\lib\site-packages\torch\nn\functional.py", line 2451, in batch_norm
    input, weight, bias, running_mean, running_var, training, momentum, eps, torch.backends.cudnn.enabled
torch.cuda.OutOfMemoryError: CUDA out of memory. Tried to allocate 68.00 MiB (GPU 0; 8.00 GiB total capacity; 7.12 GiB already allocated; 0 bytes free; 7.26 GiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation.  See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF

但是我的显存是充足的

img

我的目的就是解决这个问题

模型使用的是torch.utils.data.DataLoader吗?你可以使用num_workers参数调整数据加载器中的工作线程数量。如果工作线程数量太多,可能会占用过多的内存和CPU资源,导致CUDA out of memory等问题。建议将num_workers设置为1或2,然后逐步增加

你是什么环境使用的

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索、baidu搜索等,得到内容具体如下。

这是CUDA显存不足的错误。说明在运行CPU推理或者CUDA推理时,显存不够用了。
有几个原因可能导致这个问题:

1、显存太小 - 如果你的GPU显存较小,试运行一个更小模型或者降低batchsize能解决问题。
2、内存分配太碎碎的 - PyTorch在内存分配时会保留一定的未使用区域以防内存碎片化。如果分配太小,这个未使用区域就占用了大部分显存,导致实际可用显存不足。使用max_split_size_mb参数可以改进这一点。
3、数据处理太大 - 你的数据,中间特征图等占用了太多显存,导致模型推理时显存不够。尝试使用更小输入尺寸,或使用hesis方式进行训练。
4、bug - 有些CUDA操作或 PyTorch内存管理有bug,导致显存泄漏或过度占用。确认你使用的是最新版本的CUDA和PyTorch可以排除这一 possibility。

所以,解决这个问题的方法主要有:

1、增加显存大小 - 如果有可能的话,升级到更大显存的GPU。
2、优化内存分配 - 使用max_split_size_mb参数将分配粒度扩大,减少未使用区域。
3、减少输入大小 - 使用更小的图像尺寸或batchsize进行推理。
4、使用hesitation训练 - 在训练阶段,每多运行一定的epoch,就 checkpoint 一下模型,后续恢复训练时加载这些checkpoint,避免重新算全量梯度。
5、检测并修复bug - 如有必要,检查你使用的CUDA和PyTorch版本,看是否存在已修复的相关bug。

使用哪种方法,要根据你具体的情况来选择。多试试,综合考虑训练精度和资源占用来权衡。

希望这个回答能帮助你解决CUDA显存不足问题!如有其他需要,欢迎继续提问。

如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

以下内容部分参考ChatGPT模型:


这个问题是因为你的GPU内存不足以容纳当前的模型和数据。你可以尝试以下几种方法解决:

  1. 减小batch size。这将减少一次前向传递所需要的内存。

  2. 通过torch.cuda.empty_cache()释放不需要的GPU内存。

  3. 调整模型参数,例如减小模型的大小、减少模型的深度等。

  4. 如果你的GPU显存较小,可以考虑使用更小的模型或者使用CPU进行计算。

  5. 调整PyTorch的GPU内存分配策略,可以通过设置max_split_size_mb参数来避免GPU内存碎片化问题。具体操作可以参考PyTorch官方文档中有关GPU内存管理的章节。


如果我的建议对您有帮助、请点击采纳、祝您生活愉快

在PyTorch代码中加入以下代码来释放GPU内存
import torch
torch.cuda.empty_cache()
或者使用分布式训练,将训练过程分散在多个GPU。

模型都运行不起来,何谈充足啊,目测是出现了矩阵计算量过大的代码,建议print大法查执行到哪一行出现的问题,你这个好像是测试,没有batch的问题,只可能是计算量过大导致的内存不足

问题是关于CUDA显存不足的错误,这可能是由以下原因导致的:

  • GPU显存太小,无法容纳当前的模型和数据。
  • GPU内存分配太碎片化,导致可用内存不足。
  • 数据处理太大,占用了太多的显存。
  • CUDA或PyTorch存在bug,导致显存泄漏或过度占用。

解决这个问题的方法主要有:

  • 增加显存大小,如果有可能的话,升级到更大显存的GPU。
  • 优化内存分配,使用max_split_size_mb参数将分配粒度扩大,减少未使用区域。
  • 减少输入大小,使用更小的图像尺寸或batchsize进行推理。
  • 使用hesitation训练,在训练阶段,每多运行一定的epoch,就checkpoint一下模型,后续恢复训练时加载这些checkpoint,避免重新算全量梯度。
  • 检测并修复bug,如有必要,检查你使用的CUDA和PyTorch版本,看是否存在已修复的相关bug。

CUDA使用遇到的几个问题

可以借鉴下
https://blog.csdn.net/sinat_33972705/article/details/111193163

引用chatGPT作答,由于这段代码中涉及到GPU计算,因此需要保证计算机中安装了合适版本的CUDA,并且显卡支持CUDA计算。如果出现了CUDA相关的问题,可以尝试升级或降级CUDA版本,或者检查显卡驱动是否正确安装。
您可以使用torch.cuda.memory_allocated()和torch.cuda.max_memory_allocated()函数来检查您的代码在运行时所占用的显存情况,以确定您的显存是否充足。这两个函数分别返回当前已分配显存的字节数和最大已分配显存的字节数。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
这个问题是因为在使用模型进行预测的过程中,程序试图在GPU上分配一些内存,但是已经没有可用的内存了。这可能是因为在这个程序运行之前,其他占用内存较大的任务已经使用了大部分GPU内存,或者你的模型需要使用的内存太多。尝试以下几个解决方法:

  1. 减小batch size:尝试将图像的batch size减小。这样可以减少每个batch需要占用的内存,从而减少占用的总内存。

  2. 缩小图像尺寸:可以尝试将图像尺寸缩小,这样可以减少每个图像需要占用的内存。

  3. 释放不必要的变量:在程序运行的过程中,可能存在一些被分配的变量占用了较多的内存,但是后续并没有被使用。可以通过手动释放这些变量释放内存。可以使用Python的del语句来删除不需要的变量。

  4. 减少模型复杂度:如果模型非常大,有很多参数,可以尝试减少模型的复杂度,例如减少模型的层数、减少卷积核的数量等等。

  5. 使用PyTorch的内存管理选项:在一些情况下,可以使用PyTorch内置的内存管理参数来控制内存的分配和释放。可以参考官方文档。
    如果我的回答解决了您的问题,请采纳!