[Tensorflow2.x] Establecer GPU (crecimiento propio de memoria, GPU designada)

cada blog, cada lema: puedes hacer más de lo que crees.

0. Prefacio

Esta sección explica principalmente la configuración de la GPU. Específicamente, cómo ahorrar recursos de GPU. No hay mucho que decir, veamos el tema principal a continuación:

1. Texto

1.1 Introducción

  1. tensorflow llenará la GPU (tanto como sea posible) de forma predeterminada, lo que hará que otros programas no puedan usar la GPU, lo que resultará en un desperdicio de memoria y recursos informáticos de la GPU. Por lo general, existen los siguientes métodos:
  • Establecer el crecimiento personal de la memoria
  • Mecanismo de dispositivo virtual (similar a un disco de ventana)
  1. Uso de múltiples GPU
  • GPU virtual y GPU real
  • Configuración manual y mecanismo distribuido

  1. Descripción de la lista de API : el comentario está debajo del código correspondiente
tf.debugging.set_log_device_placement  
# 打印变量在哪个设备上
tf.config.experimental.set_visible_devices  
# 设置对本进程可见的设备
tf.config.experimental.list_logical_devices  
# 获取所有的逻辑设备
tf.config.experimental.list_physical_devices  
# 获取物理设备的列表
tf.config.experimental.set_memory_growth  
# 设置内存自增长
tf.config.experimental.VirtualDeviceConfiguration  
# 建立逻辑分区
tf.config.set_soft_device_placement 
# 自动分配变量到某个设备上
  1. Supervisar las condiciones de la GPU
  • General
    Ingrese en la consola de la ventana (win + R -> cmd) o en la terminal de Linux
nvidia-smi

  • Ventana de monitoreo en tiempo real
nvidi-smi -l

linux (ubuntu):

watch -n 0.1 nvidia-smi 

1.2 Establecer el crecimiento personal de la memoria

De forma predeterminada, el programa tendrá la memoria de la GPU (como) al máximo, aunque no usó tanta memoria, como se muestra a continuación:
Inserte la descripción de la imagen aquí
Al comienzo de la posición del programa , configure la memoria desde el crecimiento, de la siguiente manera:
Nota: En Al comienzo del programa, configure el crecimiento propio de la memoria para la GPU y llame a la siguiente función.

def set_GPU():
    """GPU相关设置"""

    # 打印变量在那个设备上
    # tf.debugging.set_log_device_placement(True)
    # 获取物理GPU个数
    gpus = tf.config.experimental.list_physical_devices('GPU')
    print('物理GPU个数为:', len(gpus))
    # 设置内存自增长
    for gpu in gpus:
        tf.config.experimental.set_memory_growth(gpu, True)
    print('-------------已设置完GPU内存自增长--------------')
    # 获取逻辑GPU个数
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print('逻辑GPU个数为:', len(logical_gpus))

Inserte la descripción de la imagen aquí
El uso de la GPU es el siguiente:
Inserte la descripción de la imagen aquí

1.3 Especificar la GPU para que sea visible

Por defecto, el programa usará la primera GPU, podemos especificarlo, es decir, dejar que el programa se ejecute en la GPU que especifiquemos. el código se muestra a continuación:

def set_GPU():
    """GPU相关设置"""

    # 打印变量在那个设备上
    # tf.debugging.set_log_device_placement(True)
    # 获取物理GPU个数
    gpus = tf.config.experimental.list_physical_devices('GPU')
    print('物理GPU个数为:', len(gpus))
    # 设置内存自增长
    for gpu in gpus:
        tf.config.experimental.set_memory_growth(gpu, True)
    print('-------------已设置完GPU内存自增长--------------')

    # 设置哪个GPU对设备可见,即指定用哪个GPU
    tf.config.experimental.set_visible_devices(gpus[-1], 'GPU')
    # 获取逻辑GPU个数
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print('逻辑GPU个数为:', len(logical_gpus))

Inserte la descripción de la imagen aquí
Descripción:

  1. La máquina tiene solo 1 GPU, por lo que el programa se ejecuta en el servidor, por lo que la información de nvidia es ligeramente diferente.
  2. Como se muestra en el código, especificamos que la última GPU es visible, es decir, usamos la última GPU.
  3. Todavía hay dos GPU físicas y ahora solo hay una GPU lógica.
  4. Entre ellos, todavía establecemos el crecimiento personal de la memoria.
    Inserte la descripción de la imagen aquíInserte la descripción de la imagen aquí

1.4 segmentación de GPU

Descripción:

  1. Similar a dividir un disco físico en varias zonas, es decir, cuando usamos habitualmente la computadora, puede que solo haya un disco físico en la computadora, pero lo dividiremos en varias zonas, como la unidad C, la unidad D, etc.
  2. GPU física, es decir, una GPU real; GPU lógica, es decir, GPU virtual (mapeo de GPU física a GPU lógica)
def set_GPU():
    """GPU相关设置"""

    # 打印变量在那个设备上
    # tf.debugging.set_log_device_placement(True)
    # 获取物理GPU个数
    gpus = tf.config.experimental.list_physical_devices('GPU')
    print('物理GPU个数为:', len(gpus))
    # 设置内存自增长
    # for gpu in gpus:
    #     tf.config.experimental.set_memory_growth(gpu, True)
    # print('-------------已设置完GPU内存自增长--------------')

    # 设置哪个GPU对设备可见,即指定用哪个GPU
    tf.config.experimental.set_visible_devices(gpus[-1], 'GPU')
    # 切分逻辑GPU
    tf.config.experimental.set_virtual_device_configuration(
        gpus[-1],  # 指定要切割的物理GPU
        # 切割的个数,和每块逻辑GPU的大小
        [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=4096),
         tf.config.experimental.VirtualDeviceConfiguration(memory_limit=4096), ]
    )
    # 获取逻辑GPU个数
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print('逻辑GPU个数为:', len(logical_gpus))

Inserte la descripción de la imagen aquí
Como se muestra en la figura siguiente, decimos que la última GPU física está dividida en dos partes. Ahora el número de GPU lógicas es 2, que es diferente de la GPU lógica de 1 en (1.2) anterior.
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

1.5 Uso de un entorno multi-GPU

1.5.1 Especificar manualmente

el código se muestra a continuación:

import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
  
gpus = tf.config.experimental.list_physical_devices('GPU')
print('物理GPU个数为:', len(gpus))
# 设置内存自增长
for gpu in gpus:
    tf.config.experimental.set_memory_growth(gpu, True)
print('-------------已设置完GPU内存自增长--------------')

# 获取逻辑GPU个数
logical_gpus = tf.config.experimental.list_logical_devices('GPU')
print('逻辑GPU个数为:', len(logical_gpus))

c = []
# 手动指定多GPU环境
for gpu in logical_gpus:
    print(gpu.name)
    with tf.device(gpu.name):
        a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
        b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
        c.append(tf.matmul(a, b))
with tf.device('/CPU:0'):
    matmul_sum = tf.add_n(c)
print(matmul_sum)

Inserte la descripción de la imagen aquí
dañar:

  1. Demasiados detalles para controlar
  2. Algunos dispositivos no son compatibles

1.5.2 Estrategia distribuida

Inserte la descripción de la imagen aquí

1. Estrategia reflejada

  • Entrenamiento distribuido sincrónico
  • Adecuado para una máquina con varias tarjetas
  • Cada GPU tiene todos los parámetros de la estructura de la red, estos parámetros se sincronizarán
  • Paralelo de datos
    • Los datos por lotes se cortan en N copias en cada GPU
    • Luego, la agregación de gradientes se actualiza a los parámetros de cada GPU

2. CentralStorageStrategy

  • Variante de MirroredStrategy
  • Los parámetros no se almacenan en cada GPU, sino que se almacenan en un dispositivo
    • CPU o solo GPU
  • El cálculo es paralelo en todas las GPU
    • Además del cálculo de los parámetros de actualización

3. MultiWorkerMirroredStrategy

  • Similar a MirroredStrategy
  • Adecuado para situaciones de múltiples máquinas y tarjetas

4. TPUStrategy

  • Similar a MirroredStrategy
  • Usa la estrategia en TPU

4. ParameterServerStrategy

  • Distribuido asincrónico
  • Más adecuado para sistemas distribuidos
  • La máquina se divide en dos categorías: servidor de parámetros y trabajador
    • El servidor de parámetros es responsable de integrar gradientes y actualizar parámetros
    • El trabajador es responsable de la informática y la formación de la red.

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Los pros y los contras de la sincronización y la asincronía

  • Multitarjeta multimáquina
    • La asincronía puede evitar efectos de tabla corta
  • Una máquina con varias tarjetas
    • La sincronización puede evitar una comunicación excesiva
  • Los cálculos asincrónicos aumentarán el alcance del modelo
    • La asincronía no es estrictamente correcta, por lo que el modelo es más fácil de tolerar errores.

1.6 Resumen

Formas de ahorrar recursos de memoria de la GPU:

  • Crecimiento propio
  • Segmentación lógica

referencias

[1] https://blog.csdn.net/weixin_39190382/article/details/104739572

Supongo que te gusta

Origin blog.csdn.net/weixin_39190382/article/details/110533410
Recomendado
Clasificación