【问题标题】:How to prevent appending to a list to fill gpu memory如何防止附加到列表以填充 gpu 内存
【发布时间】:2021-09-18 01:50:21
【问题描述】:

我使用带有批量推理的 pytorch 运行模型。我想将该模型的输出保存到一个列表中,因为稍后我需要它来进行其他计算。问题是,如果我将模型的输出附加到我的列表“输出”中,它会填满 gpu 内存。 模型的输出是一个列表。 有没有办法将列表移动到 RAM 中?

if __name__ == "__main__":
        output = []
        with torch.no_grad():
            for i in input_split:
                try:
                    preds = model(i)                        
                    output.append(preds)          
                    del preds   
                    gc.collect()
                    torch.cuda.empty_cache()    

                except RuntimeError as e:
                    print("Failed")

【问题讨论】:

    标签: python memory pytorch gpu


    【解决方案1】:

    这是因为您从preds = model(i) 获得的张量仍在 GPU 中。

    您可以在将它们附加到列表之前将它们从 GPU 中取出

    output = []
    with torch.no_grad():
        for i in input_split:
            preds = model(i)
            output.append(preds.cpu())
    

    当你想在 GPU 中再次使用它们时,只需将它们一个一个放入 GPU 中

    for data in output:
        data = data.cuda()
    

    编辑 1. Detectron2

    这类似于上面的答案,只是稍微复杂一点。

    Detectron2 的输出是list[dict]。这意味着如果批处理中有超过 1 个图像,则必须创建一个空列表作为缓冲区,例如

    output = []
    with torch.no_grad():
        for i in input_split:
            preds = model(i)
            
            buffer = []
            for pred in preds:
                pred['instances']['pred_boxes'] = pred['instances']['pred_boxes'].cpu()
                pred['instances']['scores'] = pred['instances']['scores'].cpu()
                pred['instances']['pred_classes'] = pred['instances']['pred_classes'].cpu()
                pred['instances']['pred_masks'] = pred['instances']['pred_masks'].cpu()
                pred['instances']['pred_keypoints'] = pred['instances']['pred_keypoints'].cpu()
                buffer.append(pred)
            output.append(buffer)
    

    你也许也可以像这样使用指针并摆脱缓冲区

    output = []
    with torch.no_grad():
        for i in input_split:
            preds = model(i)
            
            for pred in preds:
                pred['instances']['pred_boxes'] = pred['instances']['pred_boxes'].cpu()
                pred['instances']['scores'] = pred['instances']['scores'].cpu()
                pred['instances']['pred_classes'] = pred['instances']['pred_classes'].cpu()
                pred['instances']['pred_masks'] = pred['instances']['pred_masks'].cpu()
                pred['instances']['pred_keypoints'] = pred['instances']['pred_keypoints'].cpu()
            output.append(preds)
    

    【讨论】:

    • 这不起作用:回溯(最近一次调用最后一次):文件“/home/test/ML_Seg/AdelaiDet/demo/demo_inference.py”,第 307 行,在 output.append( preds.cpu()) AttributeError: 'list' object has no attribute 'cpu'
    • 所以preds 是一个列表?然后你需要将所有这些元素分成张量。喜欢a, b, c = model(i)。如果您不明白这意味着什么,请将model 的代码放在主要问题中。
    • 我使用detectron2:detectron2.readthedocs.io/en/latest/tutorials/models.html进行图像分割。该链接包含输出格式。这有帮助吗?感谢您的帮助!
    • i 是一批多张图片还是只有一张图片? Detectron2 更容易处理 1 张图像
    • i 是一组多张图片(例如 5 张)。如果图像分辨率低于 800x800,它可以工作,但我需要它是 1000x1000。如果我不将输出附加到列表中,则仅使用 4gb 的 gpu 内存。所以添加到列表中肯定是问题所在。
    猜你喜欢
    • 2021-10-19
    • 2016-03-15
    • 2013-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多