memoria de la GPU cómo hacer menor que la profundidad de la formación modelo de red neuronal?

prefacio

Recientes ejecución del modelo relativamente grande, especialmente Bert, esto es muy difícil para mí 1080ti, y en el truco oficial del Ejemplo Bert proporciona algún tipo de formación que ayuda a acelerar, muy consciente, pero todavía se siente no es suficiente, entonces tomamos un tiempo truco reunido una colección para ayudarnos a reír cuando la memoria es insuficiente.

Este documento se divide en dos partes, la primera parte de la introducción de un tema: la forma de estimar el modelo de memoria requerida, el segundo tema: Trick variedad de GPU cuando la memoria es insuficiente.

GPU monitor

El mayoritariamente utilizado para la GPU monitor, por supuesto, nvidia-gar, pero hay una herramienta que puede mostrar mejor la información: gpustat.

nvidia-smi
watch --color -n1 gpustat -cpu   # 动态事实监控GPU

Se recomienda en los alias del archivo de configuración, de todos modos, cada vez que miro GPU, la información es todo lo alto, muy conveniente.

Aquí están los estudiantes nvtop recomendadas, simplemente me trataron, muy bueno, parecen mostrar la información es muy rica, se recomienda probar.

Cómo estimar el modelo de memoria [1]
En primer lugar, ponderando una pregunta: ¿Qué modelos cosas ocupan mi memoria, fuerte ruido cada resultan de la memoria?

De hecho, una memoria principal ocupado por el modelo consta de dos partes: los propios parámetros del modelo, la optimización de los parámetros, los datos del modelo y salidas de cada capa.

propio modelo de parámetros

Los parámetros del modelo en sí se refiere al peso y Bias cada capa de red, que es parte de la memoria será ocupado después de que el modelo ha terminado de cargar, señaló que hay algunos parámetros de nivel, tales como CNN, RNN, y algunas capas no son parámetros, tales como la capa activa, capa agruparon.

Desde el punto de vista Pytorch, cuando se ejecuta model.to (dispositivo), se carga el modelo, entonces el modelo ha sido cargado.

Para Pytorch, los parámetros del modelo se almacenan en model.parameters (), por lo que no necesitamos sus propios cálculos, se pueden imprimir directamente por Pytorh:

print('Model {} : params: {:4f}M'.format(model._get_name(), para * type_size / 1000 / 1000))

parámetros de optimización

Optimización de los parámetros se refiere a un proceso de optimización de parámetros del modelo que es el reverso de la propagación generado, que se refiere principalmente a la parte de los parámetros DW, es decir, gradiente, en SGD, que es del mismo tamaño y los parámetros, los parámetros de período y, por tanto, en el modelo de optimización ocupada por la memoria y se duplicará.

Cabe destacar que, a diferencia de optimización se requiere diferentes parámetros de optimización que se almacenan, para Adán, ya que necesita para salvar el resto de parámetros, los parámetros del modelo que se cuadruplicará en el intervalo de optimización.

Cada modelo de entrada-salida

En primer lugar , el primer punto es ocupado por la entrada de datos de la memoria, esta parte de la memoria ocupado no es grande, es porque tendemos a leer los datos utilizando de forma iterativa, lo que significa que en realidad no somos todos de una sola vez lectura de la memoria de datos, que es garantizar que toda la memoria de parámetros de la red ocupado por cada relación de entrada es insignificante.

Entonces , cuando la propagación inversa para propagación antes de que el modelo, una cosa muy importante es calcular y guardar la salida, así como su correspondiente gradiente de cada capa, lo que significa que también ocupa una gran parte de la memoria.

Por último , los resultados del modelo de uso de memoria se pueden resumir de la siguiente manera:

  • La salida de cada capa (matriz multi-dimensional), que corresponde a la pendiente, se hace notar que la salida del modelo no tiene que almacenar la información correspondiente impulso (es decir, si se usa en el presente documento, Adam, los parámetros de salida del modelo es todavía una cantidad de 2 veces 4 veces en lugar de no sé por qué ?? jefes buscan consejo)
  • El uso de memoria y de salida de lotes proporcional al tamaño

¿Hay una manera de calcular esta cantidad por algunos parámetros que Pytorch? La respuesta es sí, podemos suponer que una muestra del lote y después) para cada capa por model.modules (recorrido, obtener cada forma de capa de salida, entonces se puede obtener la cantidad de parámetros de salida de un lote de datos. [2]

Todos los cálculos uso de la memoria

显存占用 = 模型自身参数 × n + batch size × 输出参数量 × 2 + 一个batch的输入数据(往往忽略)

En el que, siendo n conjunto de acuerdo con el algoritmo de optimización, si la elección de la SGD, entonces n = 2, si el Adam seleccionado, entonces n = 4.

Logrado un gran seguimiento, no molesto a re-escritura, puede modificarlo para leer esto, no hay problema.

# 模型显存占用监测函数
# model:输入的模型
# input:实际中需要输入的Tensor变量
# type_size 默认为 4 默认类型为 float32 
 
def modelsize(model, input, type_size=4):
    para = sum([np.prod(list(p.size())) for p in model.parameters()])
    print('Model {} : params: {:4f}M'.format(model._get_name(), para * type_size / 1000 / 1000))
 
    input_ = input.clone()
    input_.requires_grad_(requires_grad=False)
 
    mods = list(model.modules())
    out_sizes = []
 
    for i in range(1, len(mods)):
        m = mods[i]
        if isinstance(m, nn.ReLU):
            if m.inplace:
                continue
        out = m(input_)
        out_sizes.append(np.array(out.size()))
        input_ = out
 
    total_nums = 0
    for i in range(len(out_sizes)):
        s = out_sizes[i]
        nums = np.prod(np.array(s))
        total_nums += nums
 
 
    print('Model {} : intermedite variables: {:3f} M (without backward)'
          .format(model._get_name(), total_nums * type_size / 1000 / 1000))
    print('Model {} : intermedite variables: {:3f} M (with backward)'
          .format(model._get_name(), total_nums * type_size*2 / 1000 / 1000))

GPU truco cuando la memoria es insuficiente [2]

Por no hablar de la multi-GPU aquí, la computación distribuida, etc., sólo para discutir algunos de dibujo convencional, será actualizada de vez en cuando.

Reducir el tamaño del lote

Debe entenderse bien que adecuada para reducir el tamaño del lote, el modelo de entrada-salida de cada capa se reducirá linealmente, el efecto es bastante obvio. Una cosa a tener en cuenta es que el tamaño de ajuste dev lotes también ayuda a reducir la memoria, al mismo tiempo, no ajuste el tamaño del lote para la longitud dev o muestra de ensayo de deformación, hace poco hice esta cosa estúpida, daño, depurar el día antes que sean trasladados fuera de la cuestión.

Selección de un tipo de datos más pequeña

En general por defecto, toda la red utiliza una coma flotante de 32 bits, si la conmutación al número de coma flotante de 16 bits, que estará cerca de la cantidad de uso de la memoria estaba disminuyendo múltiplos.

Los modelos compactos

En el diseño del modelo, modelos apropiados compactos, tales como la capa original en dos capas LSTM; LSTM uso original, ahora GRU, reducir el número de granos de convolución; Minimizar el uso de Linear similares.

ángulo de datos

Para los datos de texto, la cantidad de parámetro de longitud de secuencia se incrementa linealmente para traer los parámetros apropiados reducir en gran medida la cantidad de longitud de la secuencia puede ser reducido.

pérdida total

Teniendo en cuenta la pérdida en sí es un tensor gradiente que contiene información, y por lo tanto, la forma correcta de encontrar y la pérdida:

total_loss += loss.item()

La liberación de un tensor y las variables

Del comunicado de usar y tensor de variables que ya no es necesario, sino que también nos obliga a prestar atención a las variables utilizadas en el modelo al escribir, no lo hacen arbitraria, volando en el cielo.

RELU parámetros de inplace

Relu función de activación () hay un in-situ de parámetros por defecto, el valor predeterminado es Falso, cuando se establece en True, que en el nuevo valor por relu () calculado sin ocupar un nuevo espacio, pero sobreescribir directamente el valor original, lo que representa el conjunto es cierto, se puede ahorrar algo de memoria.

gradiente acumulativo

En primer lugar, hay que entender algunos conocimientos básicos de Pytorch:

  • En Pytorch, cuando ejecutamos loss.backward (), se calcula un gradiente para cada parámetro y se almacena en paramter.grad, se observa, es un paramter.grad tensor, que se añaden juntas para dar a cada gradiente.
  • En Pytorch, sólo para llamar optimizer.step (descenso de gradiente se actualizará los parámetros de red).

Sabemos, tamaño del lote y la huella de la memoria están estrechamente relacionados, pero a veces nuestro tamaño del lote es demasiado pequeño y no se puede ajustar, lo que supone que debemos hacer? La respuesta es acumulan gradiente .

Vamos a echar un vistazo a la formación tradicional:

for i,(feature,target) in enumerate(train_loader):
    outputs = model(feature)  # 前向传播
    loss = criterion(outputs,target)  # 计算损失
 
    optimizer.zero_grad()   # 清空梯度
    loss.backward()  # 计算梯度
    optimizer.step()  # 反向传播, 更新网络参数

Después de la adición de la acumulación de gradiente, el código es tal que:

for i,(features,target) in enumerate(train_loader):
    outputs = model(images)  # 前向传播
    loss = criterion(outputs,target)  # 计算损失
    loss = loss/accumulation_steps   # 可选,如果损失要在训练样本上取平均
 
    loss.backward()  # 计算梯度
    if((i+1)%accumulation_steps)==0:
        optimizer.step()        # 反向传播,更新网络参数
        optimizer.zero_grad()   # 清空梯度

Comparación, se encontró que el gradiente es esencialmente gradiente acumulativo acumulativo accumulation_steps un lote, y luego actualizar los parámetros de red basados ​​en gradiente acumulado, con el fin de lograr un efecto similar como batch_size accumulation_steps batch_size * de. En uso, la necesidad de prestar atención apropiadas para ampliar la tasa de aprendizaje.

Más específicamente, se supone que el tamaño del lote = 32, pasos de acumulación = 8, cuando la acumulación gradiente primera propagación hacia adelante hablando en pasos de acumulación de partes por lotes, y luego obtener el tamaño = pequeños lotes 4 partes, cada una en un pequeño lote para calcular el gradiente, pero no actualiza los parámetros, el gradiente acumula hasta que se calcularon las medidas de acumulación de lotes pequeños, vamos a actualizar los parámetros.

la acumulación de gradiente puede aliviar en gran medida los problemas de escasez de memoria de la GPU, recomendó.

Bert está en el almacén, en el uso de este truco, muy práctico, no es más que nuestra conciencia truco mendigo laboratorio.

gradiente de Checkpoint

Trick No he utilizado esto, después de todo, no era tan grande como el modelo.

Y por lo que utiliza entonces actualizarla, primera fosa cavada.

finalmente

Hey, si usted lee este artículo, significa una cosa: ** Joven, la tarjeta no es suficiente ah. ** bueno, mendigos no merecen profunda laboratorio de aprendizaje, llorando.

Referencia

[1] mensajes ciencia: GPU aprendizaje profundidad y análisis de la memoria

[2] cómo refinó el uso de memoria en Pytorch

[3] GPU en apuros para entrenarlo con modelo de alto volumen? Que no pueden

[4] PyTorch ¿Por qué se borre manualmente antes de que el gradiente de propagación hacia atrás?

[5] De cero a la investigación - Una introducción a la Meta-aprendizaje

[6] Formación Redes Neuronales en grandes lotes: consejos prácticos para 1-GPU, multi-GPU y configuraciones distribuidas

Publicado siete artículos originales · ganado elogios 4 · Vistas 210

Supongo que te gusta

Origin blog.csdn.net/Zserendipity/article/details/105301983
Recomendado
Clasificación