Как рассчитать оптимальный размер партии

Иногда я сталкиваюсь с проблемой:

ООМ при выделении тензора с формой

уравнение

ООМ при выделении тензора с формой (1024, 100, 160)

Где 1024 - размер моей партии, а я не знаю, что остальное. Если я уменьшу размер партии или количество нейронов в модели, она будет работать нормально.

Существует ли общий способ расчета оптимального размера пакета на основе модели и памяти графического процессора, чтобы программа не вылетала?

РЕДАКТИРОВАТЬ

Поскольку мой вопрос может показаться неясным, позвольте мне сказать по-своему: я хочу максимально возможный размер пакета с точки зрения моей модели, который поместится в моей памяти GPU и не приведет к сбою программы.

РЕДАКТИРОВАТЬ 2

Тем, кто голосовал за закрытие вопроса за его слишком широкость: Насколько этот вопрос слишком широк? Существует некоторый алгоритм, который выбирает часть данных для помещения в память графического процессора. Это явно несовершенно, поскольку данные иногда превышают объем памяти графического процессора. Вопрос о том, как работает алгоритм для предотвращения случайных сбоев, кажется мне вполне разумным.

3 ответа

Решение

Вы можете оценить самый большой размер партии, используя:

Максимальный размер пакета = доступные байты памяти GPU / 4 / (размер тензоров + обучаемые параметры)

Из недавней книги Глубокого обучения Гудфеллоу и др., Глава 8:

Размеры мини-партии обычно определяются следующими факторами:

  • Большие партии обеспечивают более точную оценку градиента, но с менее чем линейной отдачей.
  • Многоядерные архитектуры обычно недостаточно используются очень маленькими партиями. Это мотивирует использование некоторого абсолютного минимального размера партии, ниже которого не происходит сокращения времени на обработку мини-партии.
  • Если все примеры в пакете должны обрабатываться параллельно (как это обычно бывает), то объем памяти масштабируется в зависимости от размера пакета. Для многих аппаратных установок это является ограничивающим фактором в размере пакета.
  • Некоторые виды аппаратного обеспечения достигают лучшего времени выполнения с определенными размерами массивов. Особенно при использовании графических процессоров, как правило, для мощности 2-х размеров пакетов предлагается лучшее время выполнения. Типичная мощность двух размеров пакета варьируется от 32 до 256, при этом иногда пытаются использовать 16 для больших моделей.
  • Небольшие партии могут предлагать регуляризирующий эффект (Wilson and Martinez, 2003), возможно, из-за шума, который они добавляют к процессу обучения. Ошибка обобщения часто лучше всего подходит для размера партии 1. Для обучения с таким небольшим размером партии может потребоваться небольшая скорость обучения для поддержания стабильности из-за высокой дисперсии в оценке градиента. Общее время выполнения может быть очень высоким из-за необходимости делать больше шагов, как из-за уменьшенной скорости обучения, так и из-за того, что требуется больше шагов для наблюдения всего учебного набора.

Что на практике обычно означает "в степени 2 и больше, тем лучше, при условии, что партия помещается в вашу (GPU) память".

Вы также можете обратиться к нескольким хорошим сообщениям здесь, в Stack Exchange:

Просто имейте в виду, что статья Keskar et al. " О крупномасштабном обучении для глубокого обучения: разрыв в обобщении и острые минимумы", цитируемое несколькими постами выше, получило некоторые возражения от других уважаемых исследователей из сообщества глубокого обучения.

Надеюсь это поможет...

ОБНОВЛЕНИЕ (декабрь 2017 г.): есть новый документ Йошуа Бенжио и команды, " Три фактора, влияющие на минимумы в SGD" (ноябрь 2017 г.); Стоит прочитать в том смысле, что в нем сообщаются новые теоретические и экспериментальные результаты о взаимодействии между скоростью обучения и размером партии.

Используйте сводки, предоставленные pytorchsummary (установка pip) или keras (встроенный).

Например

from torchsummary import summary
summary(model)
.....
.....
================================================================
Total params: 1,127,495
Trainable params: 1,127,495
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.02
Forward/backward pass size (MB): 13.93
Params size (MB): 4.30
Estimated Total Size (MB): 18.25
----------------------------------------------------------------

Каждый экземпляр, который вы помещаете в пакет, потребует полного прямого / обратного прохода в памяти, ваша модель вам понадобится только один раз. Кажется, что люди предпочитают размер пакета, равный степени двойки, вероятно, из-за автоматической оптимизации макета на графическом процессоре.

Не забывайте линейно увеличивать скорость обучения при увеличении размера пакета.

Предположим, у нас есть Tesla P100 с 16 ГБ памяти.

(16000 - model_size) / (forward_back_ward_size)
(16000 - 4.3) / 18.25 = 1148.29
rounded to powers of 2 results in batch size 1024

определить функцию, чтобы найти размер партии для обучения модели

def FindBatchSize(model):
    """#model: model architecture, that is yet to be trained"""
    import os, sys, psutil, gc, tensorflow, keras
    import numpy as np
    from keras import backend as K
    BatchFound= 16

    try:
        total_params= int(model.count_params());    GCPU= "CPU"
        #find whether gpu is available
        try:
            if K.tensorflow_backend._get_available_gpus()== []:
                GCPU= "CPU";    #CPU and Cuda9GPU
            else:
                GCPU= "GPU"
        except:
            from tensorflow.python.client import device_lib;    #Cuda8GPU
            def get_available_gpus():
                local_device_protos= device_lib.list_local_devices()
                return [x.name for x in local_device_protos if x.device_type == 'GPU']
            if "gpu" not in str(get_available_gpus()).lower():
                GCPU= "CPU"
            else:
                GCPU= "GPU"

        #decide batch size on the basis of GPU availability and model complexity
        if (GCPU== "GPU") and (os.cpu_count() >15) and (total_params <1000000):
            BatchFound= 64    
        if (os.cpu_count() <16) and (total_params <500000):
            BatchFound= 64  
        if (GCPU== "GPU") and (os.cpu_count() >15) and (total_params <2000000) and (total_params >=1000000):
            BatchFound= 32      
        if (GCPU== "GPU") and (os.cpu_count() >15) and (total_params >=2000000) and (total_params <10000000):
            BatchFound= 16  
        if (GCPU== "GPU") and (os.cpu_count() >15) and (total_params >=10000000):
            BatchFound= 8       
        if (os.cpu_count() <16) and (total_params >5000000):
            BatchFound= 8    
        if total_params >100000000:
            BatchFound= 1

    except:
        pass
    try:

        #find percentage of memory used
        memoryused= psutil.virtual_memory()
        memoryused= float(str(memoryused).replace(" ", "").split("percent=")[1].split(",")[0])
        if memoryused >75.0:
            BatchFound= 8
        if memoryused >85.0:
            BatchFound= 4
        if memoryused >90.0:
            BatchFound= 2
        if total_params >100000000:
            BatchFound= 1
        print("Batch Size:  "+ str(BatchFound));    gc.collect()
    except:
        pass

    memoryused= [];    total_params= [];    GCPU= "";
    del memoryused, total_params, GCPU;    gc.collect()
    return BatchFound



#####################################################################################################
#####################################################################################################

Я столкнулся с подобной ошибкой памяти графического процессора, которая была решена путем настройки сеанса tenorflow со следующим:

# See https://www.tensorflow.org/tutorials/using_gpu#allowing_gpu_memory_growth
config = tf.ConfigProto()
config.gpu_options.allow_growth = True

см.: Google Colab Laboratory "ResourceExhaustedError" с графическим процессором

Другие вопросы по тегам