【问题标题】:RuntimeError: CUDA out of memory. Problem when re-loading the model in a loop运行时错误:CUDA 内存不足。在循环中重新加载模型时出现问题
【发布时间】:2019-04-23 06:55:34
【问题描述】:

我遇到了经典问题:CUDA 内存不足。

我想做什么:我想每次都使用不同的嵌入矩阵加载相同的模型。我必须这样做 300 次,每个维度对应单词嵌入。

我没有训练模型,这就是我使用model.eval() 的原因,我认为这足以阻止 Pytorch 创建图表。

请注意,我从未将模型或数据传递给 cuda。事实上,我想在发送代码由 GPU 执行之前使用 cpu 调试代码。

下面的循环执行一次,在第二次迭代中引发RuntimeError

我的猜测是,代码在每次迭代时都会将新模型加载到 GPU 内存中(如果没有明确指出这样做,我不知道这是可能的)。 emb_matrix 非常重,可能导致 GPU 内存崩溃。

emb_dim = 300
acc_dim = torch.zeros((emb_dim, 4))
for d in range(emb_dim):

    #create embeddings with one dimension shuffled
    emb_matrix = text_f.vocab.vectors.clone()

    #get a random permutation across one of the dimensions
    rand_index = torch.randperm(text_f.vocab.vectors.shape[0])
    emb_matrix[:, d] =  text_f.vocab.vectors[rand_index, d]

    #load model with the scrumbled embeddings
    model = load_classifier(emb_matrix, 
                            encoder_type = encoder_type)
    model.eval()
    for batch in batch_iters["test"]:
        x_pre = batch.premise
        x_hyp = batch.hypothesis
        y = batch.label

        #perform forward pass
        y_pred = model.forward(x_pre, x_hyp)        

        #calculate accuracies
        acc_dim[d] += accuracy(y_pred, y)/test_batches

        #avoid memory issues
        y_pred.detach()

    print(f"Dimension {d} accuracies: {acc_dim[d]}")   

我收到以下错误: RuntimeError: CUDA out of memory. Tried to allocate 146.88 MiB (GPU 0; 2.00 GiB total capacity; 374.63 MiB already allocated; 0 bytes free; 1015.00 KiB cached)

我尝试将模型和数据传递给 CPU,但我得到了完全相同的错误。

我四处寻找解决问题的方法,但找不到明显的解决方案。欢迎任何关于如何将模型和数据加载到正确位置,或如何在每次迭代后清理 GPU 内存的建议。

【问题讨论】:

  • torch.cuda.empty_cache()
  • 要让它完全在 CPU 上运行以进行调试,在运行程序之前运行命令 export CUDA_VISIBLE_DEVICES=-1 这确保您将无法使用 GPU,因此不会耗尽 GPU内存。
  • @Chris toch.cuda.empty_cache() 不会释放 GPU 内存,对吗?它只是将其发布到操作系统,但不会从 GPU 中卸载模型。 pytorch.org/docs/stable/cuda.html#torch.cuda.empty_cache

标签: python runtime-error pytorch


【解决方案1】:

看起来acc_dim 积累了毕业历史 - 请参阅https://pytorch.org/docs/stable/notes/faq.html

因为你只是做推理,所以应该使用with torch.no_grad():。 这将完全回避积累毕业生历史的可能问题。

model.eval() 不会阻止研究生簿记的发生,它只是切换某些层的行为,例如 dropout。 model.eval()with torch.no_grad(): 应该一起用于推理。

【讨论】:

    猜你喜欢
    • 2021-10-10
    • 1970-01-01
    • 1970-01-01
    • 2020-12-31
    • 2019-08-30
    • 1970-01-01
    • 2012-12-30
    相关资源
    最近更新 更多