Невозможно выделить память GPU, когда достаточно кеш-памяти - PullRequest
3 голосов
/ 19 января 2020

Я обучаю модель vgg16 с нуля на AWS EC2-машине глубокого обучения AMI (Ubuntu 18.04.3 LTS (GNU / Linux 4.15.0-1054- aws x86_64v)) с Python3 (CUDA 10.1 и Intel MKL) (Pytorch 1.3.1) и ошибка ниже при обновлении параметров модели.

RuntimeError: CUDA не хватает памяти. Попытка выделить 24,00 МБ (GPU 0; общая емкость 11,17 ГБ; 10,76 ГБ уже выделено; 4,81 МБ свободно; 119,92 МБ кэшировано)

Код для обновления параметров:

def _update_fisher_params(self, current_ds, batch_size, num_batch):
    dl = DataLoader(current_ds, batch_size, shuffle=True)
    log_liklihoods = []
    for i, (input, target) in enumerate(dl):
        if i > num_batch:
            break
        output = F.log_softmax(self.model(input.cuda().float()), dim=1)
        log_liklihoods.append(output[:, target])
    log_likelihood = torch.cat(log_liklihoods).mean()
    grad_log_liklihood = autograd.grad(log_likelihood, self.model.parameters())
    _buff_param_names = [param[0].replace('.', '__') for param in self.model.named_parameters()]
    for _buff_param_name, param in zip(_buff_param_names, grad_log_liklihood):
        self.model.register_buffer(_buff_param_name+'_estimated_fisher', param.data.clone() ** 2)

После отладки: log_liklihoods.append(output[:, target]) ошибка выброса строки после 157 итераций

У меня есть требуемая память, но она не выделяется, я не понимаю, почему обновление градиентов вызывает проблемы с памятью, поскольку на градиенты следует ссылаться и освобождается автоматически на каждой итерации. Есть идеи?

Я попробовал следующие решения, но не повезло.

  • Уменьшение размера пакета
  • Освобождение кеша с помощью torch.cuda.empty_cache ()
  • Уменьшение количества фильтров для уменьшения объема памяти

Технические характеристики машины:

enter image description here

1 Ответ

1 голос
/ 09 февраля 2020

Наконец-то я решил проблему с памятью! Я понял, что в каждой итерации я помещаю входные данные в новый тензор, и Pytorch генерирует новый граф вычислений. Это приводит к тому, что используемая оперативная память растет вечно. Затем я использовал функцию .detach (), и ОЗУ всегда остается на низком уровне.

self.model(input.cuda().float()).detach().requires_grad_(True)
...