Optimiza el rendimiento de TensorFlow con Profiler

Esta guía demuestra cómo usar las herramientas disponibles con TensorFlow Profiler para realizar un seguimiento del rendimiento de tus modelos de TensorFlow. Aprenderá a comprender el rendimiento de su modelo en el host (CPU), el dispositivo (GPU) o en una combinación del host y los dispositivos.

La creación de perfiles ayuda a comprender el consumo de recursos de hardware (tiempo y memoria) de las diversas operaciones (ops) de TensorFlow en su modelo y a resolver los cuellos de botella de rendimiento y, en última instancia, hacer que el modelo se ejecute más rápido.

Esta guía lo guiará a través de cómo instalar Profiler, las diversas herramientas disponibles, los diferentes modos de cómo Profiler recopila datos de rendimiento y algunas de las mejores prácticas recomendadas para optimizar el rendimiento del modelo.

Si desea un perfil de su desempeño del modelo en la nube TPU, consulte la guía de la nube de TPU .

Instale los requisitos previos de Profiler y GPU

Instale el complemento Profiler para TensorBoard con pip. Tenga en cuenta que Profiler requiere las últimas versiones de TensorFlow y TensorBoard (> = 2.2).

pip install -U tensorboard_plugin_profile

Para crear un perfil en la GPU, debe:

  1. Conoce a los controladores NVIDIA GPU y requisitos CUDA® Toolkit que aparecen en los requisitos de software de soporte TensorFlow GPU .
  2. Asegúrese de que las herramientas de NVIDIA® CUDA® de perfiles Interface (CUPTI) existe en la ruta:

    /sbin/ldconfig -N -v $(sed 's/:/ /g' <<< $LD_LIBRARY_PATH) | \
    grep libcupti
    

Si usted no tiene CUPTI en el camino, anteponer su directorio de instalación a la $LD_LIBRARY_PATH variable de entorno mediante la ejecución de:

export LD_LIBRARY_PATH=/usr/local/cuda/extras/CUPTI/lib64:$LD_LIBRARY_PATH

A continuación, ejecute el ldconfig comando de arriba de nuevo para verificar que la biblioteca se encuentra CUPTI.

Resolver problemas de privilegios

Cuando se ejecuta con perfiles CUDA® Toolkit en un entorno acoplable o en Linux, es posible que surjan problemas relacionados con privilegios insuficientes CUPTI ( CUPTI_ERROR_INSUFFICIENT_PRIVILEGES ). Ir a los Documentos Desarrollador de NVIDIA para aprender más acerca de cómo puede resolver estos problemas en Linux.

Para resolver problemas de privilegios de CUPTI en un entorno Docker, ejecute

docker run option '--privileged=true'

Herramientas de perfilador

Acceder al Perfil de la pestaña Perfil TensorBoard, que aparece sólo después de haber capturado a algunos datos del modelo.

Profiler tiene una selección de herramientas para ayudar con el análisis de rendimiento:

  • Página de descripción general
  • Analizador de canalización de entrada
  • Estadísticas de TensorFlow
  • Visor de seguimiento
  • Estadísticas del kernel de GPU
  • Herramienta de perfil de memoria
  • Visor de pod

Página de resumen

La página de descripción general proporciona una vista de nivel superior del rendimiento de su modelo durante la ejecución de un perfil. La página le muestra una página de descripción general agregada para su host y todos los dispositivos, y algunas recomendaciones para mejorar el rendimiento del entrenamiento de su modelo. También puede seleccionar hosts individuales en el menú desplegable Host.

La página de descripción general muestra los datos de la siguiente manera:

imagen

  • Rendimiento Resumen: Muestra un resumen de alto nivel de su rendimiento del modelo. El resumen de desempeño tiene dos partes:

    1. Desglose del tiempo de paso: desglosa el tiempo de paso promedio en varias categorías de dónde se dedica el tiempo:

      • Compilación: tiempo dedicado a compilar núcleos.
      • Entrada: tiempo dedicado a la lectura de datos de entrada.
      • Salida: tiempo dedicado a la lectura de datos de salida.
      • Lanzamiento del kernel: tiempo empleado por el host para lanzar kernels
      • Tiempo de cómputo del host ...
      • Tiempo de comunicación de dispositivo a dispositivo.
      • Tiempo de cómputo en el dispositivo.
      • Todos los demás, incluida la sobrecarga de Python.
    2. Precisiones de cálculo del dispositivo: informa el porcentaje de tiempo de cálculo del dispositivo que utiliza cálculos de 16 y 32 bits.

  • -Tiempo Paso Gráfico: muestra un gráfico de tiempo de la etapa dispositivo (en milisegundos) durante todos los pasos de la muestra. Cada paso se divide en varias categorías (con diferentes colores) de dónde se dedica el tiempo. El área roja corresponde a la parte del tiempo de paso que los dispositivos estuvieron inactivos esperando los datos de entrada del host. El área verde muestra cuánto tiempo estuvo realmente funcionando el dispositivo.

  • Top 10 operaciones TensorFlow en el dispositivo (por ejemplo GPU): Muestra los programas operativos en el dispositivo que corrían el más largo.

    Cada fila muestra el tiempo propio de una operación (como el porcentaje de tiempo empleado por todas las operaciones), el tiempo acumulado, la categoría y el nombre.

  • Ejecutar Medio Ambiente: Muestra un resumen de alto nivel del entorno ejecución del modelo, incluyendo:

    • Número de hosts utilizados.
    • Tipo de dispositivo (GPU / TPU).
    • Número de núcleos de dispositivo.
  • Recomendación para la siguiente etapa: Informes cuando un modelo es obligado de entrada y recomienda herramientas que puede utilizar para localizar y resolver los cuellos de botella de rendimiento del modelo.

Analizador de canalización de entrada

Cuando un programa de TensorFlow lee datos de un archivo, comienza en la parte superior del gráfico de TensorFlow de manera canalizada. El proceso de lectura se divide en múltiples etapas de procesamiento de datos conectadas en serie, donde la salida de una etapa es la entrada a la siguiente. Este sistema de lectura de datos se llama la tubería de entrada.

Una canalización típica para leer registros de archivos tiene las siguientes etapas:

  1. Lectura de archivos.
  2. Procesamiento previo de archivos (opcional).
  3. Transferencia de archivos del host al dispositivo.

Una canalización de entrada ineficiente puede ralentizar gravemente su aplicación. Se considera que una solicitud de entrada obligada cuando se pasa una porción significativa de tiempo en la tubería de entrada. Utilice la información obtenida del analizador de canalización de entrada para comprender dónde es ineficiente la canalización de entrada.

El analizador de canalización de entrada le indica inmediatamente si su programa está vinculado a la entrada y lo guía a través del análisis del lado del dispositivo y del host para depurar los cuellos de botella de rendimiento en cualquier etapa de la canalización de entrada.

Consulte la guía sobre el rendimiento de la canalización de entrada para conocer las mejores prácticas recomendadas para optimizar las canalizaciones de entrada de datos.

Panel de control de canalización de entrada

Para abrir el analizador de la tubería de entrada, seleccione el perfil y seleccione input_pipeline_analyzer en el menú desplegable Herramientas.

imagen

El tablero contiene tres secciones:

  1. Resumen: Resume la tubería general de entrada con información sobre si su solicitud es obligado de entrada y, en caso afirmativo, en qué medida.
  2. Análisis del lado del dispositivo: Muestra detallada, los resultados del análisis dispositivo del lado, incluyendo el dispositivo de paso de tiempo y el intervalo de tiempo de dispositivo gastado a la espera de los datos de entrada a través de los núcleos en cada paso.
  3. Análisis del lado del anfitrión: muestra un análisis detallado sobre el lado del anfitrión, incluyendo un desglose de tiempo de tratamiento de entrada en el anfitrión.

Resumen de canalización de entrada

El resumen informa si su programa es de entrada con destino al presentar el porcentaje de tiempo gastado en el dispositivo de espera para la entrada desde el host. Si está utilizando una canalización de entrada estándar que se ha instrumentado, la herramienta informa dónde se gasta la mayor parte del tiempo de procesamiento de entrada.

Análisis del lado del dispositivo

El análisis del lado del dispositivo proporciona información sobre el tiempo empleado en el dispositivo frente al host y cuánto tiempo del dispositivo se dedicó a esperar los datos de entrada del host.

  1. Tiempo Paso representa frente a número de paso: muestra un gráfico de tiempo de la etapa dispositivo (en milisegundos) durante todos los pasos de la muestra. Cada paso se divide en varias categorías (con diferentes colores) de dónde se dedica el tiempo. El área roja corresponde a la parte del tiempo de paso que los dispositivos estuvieron inactivos esperando los datos de entrada del host. El área verde muestra cuánto tiempo estuvo realmente funcionando el dispositivo.
  2. Estadísticas del tiempo de paso: Informes de la desviación media, estándar, y el rango ([mínimo, máximo]) del tiempo de paso del dispositivo.

Análisis del lado del host

El análisis del host informa de un desglose del tiempo de procesamiento de entrada (el tiempo empleado en tf.data ops API) en el host en varias categorías:

  • Leer datos de archivos en la demanda: El tiempo dedicado a la lectura de datos de archivos sin necesidad de almacenamiento en caché, la obtención previa, y el entrelazado.
  • La lectura de los datos de los archivos de antemano: El tiempo dedicado a la lectura de archivos, incluyendo el almacenamiento en caché, la obtención previa, y el entrelazado.
  • Los datos pre-procesamiento: El tiempo dedicado a operaciones de pre-procesamiento, tales como la imagen de descompresión.
  • Enqueuing datos que deben transferirse al dispositivo: El tiempo dedicado a poner los datos en una cola de entrada antes de transferir los datos al dispositivo.

Estadísticas expandir Op entrada para inspeccionar las estadísticas de las operaciones de entrada individuales y sus categorías desglosadas por el tiempo de ejecución.

imagen

Aparecerá una tabla de datos de origen con cada entrada que contiene la siguiente información:

  1. Op de entrada: muestra el nombre op TensorFlow del op entrada.
  2. Incluido: muestra el número total de casos de ejecuciones op durante el periodo de perfiles.
  3. Tiempo total (en ms): Muestra la suma acumulada de tiempo dedicado a cada uno de esos casos.
  4. Tiempo total%: muestra el tiempo total gastado en un op como una fracción del tiempo total gastado en el procesamiento de entrada.
  5. Tiempo total de sí (en ms): Muestra la suma acumulada de las veces auto gastado en cada uno de esos casos. Aquí, el tiempo propio mide el tiempo que pasa dentro del cuerpo de la función, excluyendo el tiempo que pasa en la función que llama.
  6. Tiempo total Auto%. Muestra el tiempo total de uno mismo como una fracción del tiempo total dedicado al procesamiento de entrada.
  7. Categoría. Muestra la categoría de procesamiento de la operación de entrada.

Estadísticas de TensorFlow

La herramienta de estadísticas de TensorFlow muestra el rendimiento de cada operación (op) de TensorFlow que se ejecuta en el host o dispositivo durante una sesión de creación de perfiles.

imagen

La herramienta muestra información de rendimiento en dos paneles:

  • El panel superior muestra hasta cuatro gráficos circulares:

    1. La distribución del tiempo de autoejecución de cada operación en el host.
    2. La distribución del tiempo de ejecución automática de cada tipo de operación en el host.
    3. La distribución del tiempo de autoejecución de cada operación en el dispositivo.
    4. La distribución del tiempo de ejecución automática de cada tipo de operación en el dispositivo.
  • El panel inferior muestra una tabla que informa datos sobre las operaciones de TensorFlow con una fila para cada operación y una columna para cada tipo de datos (ordene las columnas haciendo clic en el encabezado de la columna). Haga clic en el botón Exportar como CSV en el lado derecho del panel superior para exportar los datos de esta tabla como un archivo CSV.

    Tenga en cuenta que:

    • Si alguna operación tiene operaciones secundarias:

      • El tiempo total "acumulado" de una operación incluye el tiempo pasado dentro de las operaciones secundarias.

      • El tiempo total "personal" de una operación no incluye el tiempo que se pasa dentro de las operaciones secundarias.

    • Si una operación se ejecuta en el host:

      • El porcentaje del tiempo total en el dispositivo incurrido por la operación será 0.
      • El porcentaje acumulativo del tiempo total en el dispositivo hasta esta operación inclusive será 0.
    • Si una operación se ejecuta en el dispositivo:

      • El porcentaje del tiempo total en el host incurrido por esta operación será 0.
      • El porcentaje acumulativo del tiempo total de tiempo propio en el host hasta esta operación incluida será 0.

Puede optar por incluir o excluir el tiempo de inactividad en los gráficos circulares y la tabla.

Visor de seguimiento

El visor de seguimiento muestra una línea de tiempo que muestra:

  • Duraciones de las operaciones ejecutadas por tu modelo de TensorFlow
  • Qué parte del sistema (host o dispositivo) ejecutó una operación. Normalmente, el host ejecuta operaciones de entrada, procesa previamente los datos de entrenamiento y los transfiere al dispositivo, mientras que el dispositivo ejecuta el entrenamiento del modelo real.

El visor de seguimiento le permite identificar problemas de rendimiento en su modelo y luego tomar medidas para resolverlos. Por ejemplo, en un nivel alto, puede identificar si el entrenamiento de entrada o modelo toma la mayor parte del tiempo. Profundizando, puede identificar qué operaciones tardan más en ejecutarse. Tenga en cuenta que el visor de seguimiento está limitado a 1 millón de eventos por dispositivo.

Interfaz del visor de seguimiento

Cuando abre el visor de trazas, aparece mostrando su ejecución más reciente:

imagen

Esta pantalla contiene los siguientes elementos principales:

  1. Escala de tiempo: muestra las operaciones que el dispositivo y el host ejecutada en el tiempo.
  2. Panel de detalles: muestra información adicional para operaciones seleccionadas en el panel Línea de tiempo.

El panel Línea de tiempo contiene los siguientes elementos:

  1. Barra superior: Contiene varios controles auxiliares.
  2. Eje de tiempo: muestra el tiempo en relación con el principio de la traza.
  3. Sección y seguimiento de las etiquetas: Cada sección contiene varias pistas y tiene un triángulo a la izquierda que puede hacer clic para expandir y contraer la sección. Hay una sección para cada elemento de procesamiento del sistema.
  4. Herramienta de selección: Contiene varias herramientas para interactuar con el visor de seguimiento, tales como zoom, pan, Select, y el tiempo. Utilice la herramienta Cronometraje para marcar un intervalo de tiempo.
  5. Eventos: Muestran el tiempo durante el cual se ejecutó un artículo o la duración de los meta-eventos, tales como medidas de formación.
Secciones y pistas

El visor de seguimiento contiene las siguientes secciones:

  • Una sección para cada nodo de dispositivo, marcado con el número del chip dispositivo y el nodo de dispositivo dentro del chip (por ejemplo, /device:GPU:0 (pid 0) ). Cada sección de nodo de dispositivo contiene las siguientes pistas:
    • Paso: Muestra la duración de las etapas de formación que se estaban ejecutando en el dispositivo
    • TensorFlow Operaciones: Muestra la ops ejecutados en el dispositivo
    • XLA Operaciones: Muestra XLA Operaciones (OPS) que se ejecutaban en el dispositivo si XLA es el compilador utilizado (cada uno op TensorFlow se traduce en una o varias operaciones XLA La XLA compilador traduce las operaciones XLA en código que se ejecuta en el dispositivo.).
  • Una sección de subprocesos que se ejecutan en la CPU del ordenador central, etiquetada "hilos" Host. La sección contiene una pista para cada subproceso de la CPU. Tenga en cuenta que puede ignorar la información que se muestra junto a las etiquetas de las secciones.
Eventos

Los eventos dentro de la línea de tiempo se muestran en diferentes colores; los colores en sí mismos no tienen un significado específico.

El visor de trazas también puede mostrar trazas de llamadas a funciones de Python en tu programa TensorFlow. Si se utiliza el tf.profiler.experimental.start API, puede habilitar el rastreo de Python usando la ProfilerOptions namedtuple al iniciar perfilado. Alternativamente, si se utiliza el modo de muestreo para el perfil, puede seleccionar el nivel de rastreo utilizando las opciones desplegables en el diálogo Capturar perfil.

imagen

Estadísticas del kernel de GPU

Esta herramienta muestra estadísticas de rendimiento y la operación de origen de cada kernel acelerado por GPU.

imagen

La herramienta muestra información en dos paneles:

  • El panel superior muestra un gráfico circular que muestra los núcleos CUDA que tienen el mayor tiempo total transcurrido.

  • El panel inferior muestra una tabla con los siguientes datos para cada par exclusivo kernel-op:

    • Un rango en orden descendente de la duración total transcurrida de la GPU agrupada por par kernel-op.
    • El nombre del kernel lanzado.
    • El número de registros de GPU usados ​​por el kernel.
    • El tamaño total de la memoria compartida (estática + compartida dinámica) utilizada en bytes.
    • La dimensión de bloque expresa como blockDim.x, blockDim.y, blockDim.z .
    • Las dimensiones de la rejilla expresan como gridDim.x, gridDim.y, gridDim.z .
    • Si el op es elegible para usar Tensor Cores .
    • Si el kernel contiene instrucciones de Tensor Core.
    • El nombre de la operación que lanzó este kernel.
    • El número de apariciones de este par kernel-op.
    • El tiempo total transcurrido de la GPU en microsegundos.
    • El tiempo promedio transcurrido de la GPU en microsegundos.
    • El tiempo mínimo transcurrido de la GPU en microsegundos.
    • El tiempo máximo de GPU transcurrido en microsegundos.

Herramienta de perfil de memoria

La memoria de perfiles herramienta monitorea el uso de la memoria de su dispositivo durante el intervalo de perfiles. Puede utilizar esta herramienta para:

  • Depura los problemas de memoria insuficiente (OOM) al señalar el uso máximo de memoria y la asignación de memoria correspondiente a las operaciones de TensorFlow. También puede depurar problemas OOM que puedan surgir cuando se ejecuta multitenencia inferencia.
  • Depurar problemas de fragmentación de la memoria.

La herramienta de perfil de memoria muestra datos en tres secciones:

  1. Resumen del perfil de memoria
  2. Gráfico de la línea de tiempo de la memoria
  3. Tabla de desglose de memoria

Resumen del perfil de memoria

Esta sección muestra un resumen de alto nivel del perfil de memoria de su programa TensorFlow como se muestra a continuación:

El resumen del perfil de memoria tiene seis campos:

  1. Identificación de la memoria: desplegable que enumera todos los sistemas de memoria disponible del dispositivo. Seleccione el sistema de memoria que desea ver en el menú desplegable.
  2. #Allocation: El número de asignaciones de memoria realizadas durante el intervalo de perfiles.
  3. #Deallocation: El número de cancelaciones de asignación de memoria en el intervalo de perfiles
  4. Capacidad de memoria: La capacidad total (en GIBS) del sistema de memoria que se seleccione.
  5. Pico Montón Uso: El uso de la memoria de pico (en GIBS) ya que el modelo comenzó a correr.
  6. Uso de la memoria de pico: El uso de la memoria de pico (en GIBS) en el intervalo de perfiles. Este campo contiene los siguientes subcampos:
    1. Marca de tiempo: La marca de tiempo de cuando el uso de memoria mayor se presentó en el gráfico línea de tiempo.
    2. Pila de reserva: Cantidad de memoria reservada en la pila (en GIBS).
    3. Asignación de montón: cantidad de memoria asignada en el montón (en GIBS).
    4. Memoria libre: cantidad de memoria libre (en GIBS). La capacidad de memoria es la suma total de la reserva de pila, la asignación de montón y la memoria libre.
    5. Fragmentación: El porcentaje de fragmentación (menos es mejor). Se calcula como un porcentaje de (1 - Size of the largest chunk of free memory / Total free memory) .

Gráfico de línea de tiempo de memoria

Esta sección muestra un gráfico del uso de memoria (en GiB) y el porcentaje de fragmentación frente al tiempo (en ms).

imagen

El eje X representa la línea de tiempo (en ms) del intervalo de perfil. El eje Y de la izquierda representa el uso de memoria (en GiB) y el eje Y de la derecha representa el porcentaje de fragmentación. En cada momento del eje X, la memoria total se divide en tres categorías: pila (en rojo), montón (en naranja) y libre (en verde). Desplácese sobre una marca de tiempo específica para ver los detalles sobre los eventos de asignación / desasignación de memoria en ese punto, como se muestra a continuación:

imagen

La ventana emergente muestra la siguiente información:

  • marca de tiempo (ms): La ubicación del evento seleccionado en la línea de tiempo.
  • Evento: El tipo de evento (asignación o desasignación).
  • requested_size (cuñas): La cantidad de memoria solicitada. Este será un número negativo para los eventos de desasignación.
  • allocation_size (GIBS): La cantidad real de memoria asignada. Este será un número negativo para los eventos de desasignación.
  • tf_op: El op TensorFlow que solicita la asignación / desasignación.
  • step_id: El paso de formación en el que ocurrió este evento.
  • region_type: El tipo de entidad de datos que esta memoria asignada es para. Los valores posibles son temp para temporales, output para activaciones y gradientes, y persist / dynamic para los pesos y constantes.
  • data_type: El tipo de elemento tensor (por ejemplo, uint8 para 8 bits entero sin signo).
  • tensor_shape: La forma de la tensor siendo asignado / desasigna.
  • memory_in_use (GIBS): La memoria total que está en uso en este punto de tiempo.

Tabla de desglose de memoria

Esta tabla muestra las asignaciones de memoria activa en el punto de uso máximo de memoria en el intervalo de generación de perfiles.

imagen

Hay una fila para cada TensorFlow Op y cada fila tiene las siguientes columnas:

  • Nombre op: El nombre de la op TensorFlow.
  • Tamaño de la distribución (cuñas): La cantidad total de memoria asignada a esta operación.
  • Tamaño solicitado (cuñas): La cantidad total de memoria requerida para esta operación.
  • Ocurrencias: El número de asignaciones para esta operación.
  • Tipo de región: el tipo de entidad de datos que esta memoria asignada es para. Los valores posibles son temp para temporales, output para activaciones y gradientes, y persist / dynamic para los pesos y constantes.
  • Tipo de datos: El tipo de elemento tensor.
  • Forma: La forma de los tensores asignados.

Visor de pod

La herramienta Pod Viewer muestra el desglose de un paso de capacitación en todos los trabajadores.

imagen

  • El panel superior tiene un control deslizante para seleccionar el número de paso.
  • El panel inferior muestra un gráfico de columnas apiladas. Esta es una vista de alto nivel de categorías de tiempo de paso desglosadas colocadas una encima de la otra. Cada columna apilada representa un trabajador único.
  • Cuando pasa el cursor sobre una columna apilada, la tarjeta del lado izquierdo muestra más detalles sobre el desglose de los pasos.

tf.data análisis de cuellos de botella

El tf.data herramienta de análisis de obstáculos detecta automáticamente los cuellos de botella en tf.data tuberías de entrada en su programa y proporciona recomendaciones sobre cómo solucionarlos. Funciona con cualquier programa usando tf.data independientemente de la plataforma (CPU / GPU / TPU). Su análisis y las recomendaciones se basan en esta guía .

Detecta un cuello de botella siguiendo estos pasos:

  1. Encuentre el host más vinculado a la entrada.
  2. Encuentra más lenta la ejecución de un tf.data tubería de entrada.
  3. Reconstruya el gráfico de canalización de entrada a partir de la traza del generador de perfiles.
  4. Encuentre la ruta crítica en el gráfico de canalización de entrada.
  5. Identifique la transformación más lenta en la ruta crítica como un cuello de botella.

La interfaz de usuario se divide en tres secciones: Análisis de rendimiento Resumen, Resumen de todas las entradas de tuberías y canalización Gráfico.

Resumen del análisis de desempeño

imagen

Esta sección proporciona el resumen del análisis. Se informa sobre lentos tf.data tuberías de entrada detectados en el perfil. Esta sección también muestra el host más vinculado a la entrada y su canalización de entrada más lenta con la latencia máxima. Lo más importante es que identifica qué parte de la canalización de entrada es el cuello de botella y cómo solucionarlo. La información del cuello de botella se proporciona con el tipo de iterador y su nombre largo.

Cómo leer el nombre largo del iterador tf.data

Un nombre largo se formatea como Iterator::<Dataset_1>::...::<Dataset_n> . En el nombre largo, <Dataset_n> coincide con el tipo iterador y los otros conjuntos de datos en el nombre largo representan transformaciones aguas abajo.

Por ejemplo, considere el siguiente conjunto de datos de canalización de entrada:

dataset = tf.data.Dataset.range(10).map(lambda x: x).repeat(2).batch(5)

Los nombres largos para los iteradores del conjunto de datos anterior serán:

Tipo de iterador Nombre largo
Distancia Iterador :: Lote :: Repetir :: Mapa :: Rango
Mapa Iterador :: Lote :: Repetir :: Mapa
Repetir Iterador :: Lote :: Repetir
Lote Iterador :: Lote

Resumen de todas las canalizaciones de entrada

imagen

Esta sección proporciona el resumen de todas las canalizaciones de entrada en todos los hosts. Normalmente hay una canalización de entrada. Cuando se usa la estrategia de distribución, hay una tubería de entrada de host que ejecuta el programa de tf.data código y múltiples tuberías de entrada dispositivo de recuperación de datos de la tubería de entrada de acogida y transferirla a los dispositivos.

Para cada canal de entrada, muestra las estadísticas de su tiempo de ejecución. Una llamada se considera lenta si tarda más de 50 μs.

Gráfico de canalización de entrada

imagen

Esta sección muestra el gráfico de canalización de entrada con la información del tiempo de ejecución. Puede utilizar "Host" y "Input Pipeline" para elegir qué host y canal de entrada desea ver. Ejecuciones de la tubería de entrada se ordenan por el tiempo de ejecución en el orden que se puede elegir mediante el menú desplegable Rango descendente.

imagen

Los nodos de la ruta crítica tienen contornos en negrita. El nodo de cuello de botella, que es el nodo con el tiempo de auto-tiempo más largo en la ruta crítica, tiene un contorno rojo. Los otros nodos no críticos tienen líneas discontinuas grises.

En cada nodo, Hora de inicio Indica la hora de inicio de la ejecución. El mismo nodo puede ser ejecutado varias veces, por ejemplo, si hay un Batch op en la tubería de entrada. Si se ejecuta varias veces, es la hora de inicio de la primera ejecución.

Duración total es el tiempo de pared de la ejecución. Si se ejecuta varias veces, es la suma de los tiempos de muro de todas las ejecuciones.

El tiempo es auto Tiempo total sin el tiempo solapado con sus nodos secundarios inmediatos.

"# Llamadas" es el número de veces que se ejecuta la canalización de entrada.

Recopilar datos de desempeño

TensorFlow Profiler recopila las actividades del host y los seguimientos de GPU de tu modelo de TensorFlow. Puede configurar Profiler para recopilar datos de rendimiento a través del modo programático o el modo de muestreo.

API de creación de perfiles

Puede utilizar las siguientes API para realizar la creación de perfiles.

  • Modo programático usando el TensorBoard Keras de devolución de llamada ( tf.keras.callbacks.TensorBoard )

    # Profile from batches 10 to 15
    tb_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir,
                                                 profile_batch='10, 15')
    
    # Train the model and use the TensorBoard Keras callback to collect
    # performance profiling data
    model.fit(train_data,
              steps_per_epoch=20,
              epochs=5,
              callbacks=[tb_callback])
    
  • Modo programática utilizando el tf.profiler funciones de la API

    tf.profiler.experimental.start('logdir')
    # Train the model here
    tf.profiler.experimental.stop()
    
  • Modo programático usando el administrador de contexto

    with tf.profiler.experimental.Profile('logdir'):
        # Train the model here
        pass
    

  • Modo de muestreo: Realizar en demanda de perfiles mediante el uso de tf.profiler.experimental.server.start para iniciar un servidor GRPC con su carrera de modelo TensorFlow. Después de iniciar el servidor GRPC y el funcionamiento de su modelo, puede capturar un perfil a través del botón Perfil de captura en el plugin perfil TensorBoard. Use la secuencia de comandos en la sección Instalar generador de perfiles anterior para iniciar una instancia de TensorBoard si aún no se está ejecutando.

    Como ejemplo,

    # Start a profiler server before your model runs.
    tf.profiler.experimental.server.start(6009)
    # (Model code goes here).
    #  Send a request to the profiler server to collect a trace of your model.
    tf.profiler.experimental.client.trace('grpc://localhost:6009',
                                          'gs://your_tb_logdir', 2000)
    

    Un ejemplo para crear perfiles de varios trabajadores:

    # E.g. your worker IP addresses are 10.0.0.2, 10.0.0.3, 10.0.0.4, and you
    # would like to profile for a duration of 2 seconds.
    tf.profiler.experimental.client.trace(
        'grpc://10.0.0.2:8466,grpc://10.0.0.3:8466,grpc://10.0.0.4:8466',
        'gs://your_tb_logdir',
        2000)
    

Utilice el cuadro de diálogo Captura de perfil para especificar:

  • Una lista delimitada por comas de URL de servicio de perfil o nombres de TPU.
  • Una duración de perfilado.
  • El nivel de seguimiento de llamadas de función de Python, dispositivo y host.
  • Cuántas veces desea que Profiler vuelva a intentar capturar perfiles si no tiene éxito al principio.

Creación de perfiles de bucles de entrenamiento personalizados

Al perfil bucles de formación personalizada en su código TensorFlow, instrumento del bucle de entrenamiento con el tf.profiler.experimental.Trace API para marcar los límites de paso para el analizador.

El name argumento se utiliza como prefijo para los nombres de paso, la step_num argumento de palabra clave se adjunta en los nombres de paso, y la _r argumento de palabra clave que hace que este evento de seguimiento se procesan como un evento de paso por el analizador.

Como ejemplo,

for step in range(NUM_STEPS):
    with tf.profiler.experimental.Trace('train', step_num=step, _r=1):
        train_data = next(dataset)
        train_step(train_data)

Esto permitirá el análisis de rendimiento basado en pasos de Profiler y hará que los eventos de pasos aparezcan en el visor de trazas.

Asegúrese de que incluye el conjunto de datos dentro del iterador tf.profiler.experimental.Trace marco para un análisis preciso de la tubería de entrada.

El siguiente fragmento de código es un anti-patrón:

for step, train_data in enumerate(dataset):
    with tf.profiler.experimental.Trace('train', step_num=step, _r=1):
        train_step(train_data)

Casos de uso de creación de perfiles

El generador de perfiles cubre una serie de casos de uso a lo largo de cuatro ejes diferentes. Algunas de las combinaciones son compatibles actualmente y otras se agregarán en el futuro. Algunos de los casos de uso son:

  • Vs. local perfilando remoto: Estas son dos formas comunes de la configuración del entorno de perfiles. En la creación de perfiles local, la API de creación de perfiles se llama en la misma máquina que está ejecutando su modelo, por ejemplo, una estación de trabajo local con GPU. En la generación de perfiles remota, la API de generación de perfiles se llama en una máquina diferente a la que se ejecuta su modelo, por ejemplo, en una TPU de Cloud.
  • Perfilado de varios trabajadores: Usted puede perfilar varias máquinas al utilizar las capacidades de formación distribuidos de TensorFlow.
  • Plataforma de hardware: CPU, GPU, perfil y TPU.

La siguiente tabla proporciona una descripción general rápida de los casos de uso compatibles con TensorFlow mencionados anteriormente:

API de creación de perfiles Local Remoto Varios trabajadores Plataformas de hardware
Devolución de llamada de TensorBoard Keras Soportado No soportado No soportado CPU, GPU
tf.profiler.experimental de arranque / parada API Soportado No soportado No soportado CPU, GPU
tf.profiler.experimental client.trace API Soportado Soportado Soportado CPU, GPU, TPU
API de administrador de contexto Soportado No soportado No soportado CPU, GPU

Mejores prácticas para un rendimiento óptimo del modelo

Utilice las siguientes recomendaciones según corresponda para sus modelos de TensorFlow para lograr un rendimiento óptimo.

En general, realice todas las transformaciones en el dispositivo y asegúrese de utilizar la última versión compatible de bibliotecas como cuDNN e Intel MKL para su plataforma.

Optimizar la canalización de datos de entrada

Utilice los datos del [#input_pipeline_analyzer] para optimizar su canalización de entrada de datos. Una canalización de entrada de datos eficiente puede mejorar drásticamente la velocidad de ejecución de su modelo al reducir el tiempo de inactividad del dispositivo. Trate de incorporar las mejores prácticas que se detallan en el rendimiento mejor con la API tf.data guía y abajo para hacer su tubería de entrada de datos más eficiente.

  • En general, paralelizar cualquier operación que no necesite ejecutarse secuencialmente puede optimizar significativamente la canalización de entrada de datos.

  • En muchos casos, es útil cambiar el orden de algunas llamadas o ajustar los argumentos para que funcione mejor para su modelo. Mientras optimiza la canalización de datos de entrada, compare solo el cargador de datos sin los pasos de entrenamiento y retropropagación para cuantificar el efecto de las optimizaciones de forma independiente.

  • Intente ejecutar su modelo con datos sintéticos para verificar si la canalización de entrada es un cuello de botella de rendimiento.

  • Uso tf.data.Dataset.shard para la formación multi-GPU. Asegúrese de fragmentar muy temprano en el bucle de entrada para evitar reducciones en el rendimiento. Cuando trabaje con TFRecords, asegúrese de fragmentar la lista de TFRecords y no el contenido de TFRecords.

  • Paralelizar varias operaciones ajustando dinámicamente el valor de num_parallel_calls utilizando tf.data.AUTOTUNE .

  • Considerar limitar el uso de tf.data.Dataset.from_generator ya que es más lento que ops TensorFlow puros.

  • Considere limitar el uso de tf.py_function ya que no se puede serializar y no se admite para funcionar en TensorFlow distribuida.

  • Use tf.data.Options para controlar optimizaciones estáticas a la tubería de entrada.

También lea la tf.data análisis de rendimiento de guía para obtener más orientación sobre la optimización de su tubería de entrada.

Optimizar el aumento de datos

Cuando se trabaja con datos de imagen, hacer que su aumento de datos más eficiente mediante la fundición de diferentes tipos de datos después de la aplicación de transformaciones espaciales, tales como voltear, recortar, rotar, etc.

Utilice NVIDIA® DALI

En algunos casos, como cuando tiene un sistema con una alta proporción de GPU a CPU, es posible que todas las optimizaciones anteriores no sean suficientes para eliminar los cuellos de botella en el cargador de datos causados ​​por las limitaciones de los ciclos de la CPU.

Si está utilizando las GPU NVIDIA® para la visión por ordenador y aplicaciones de audio de aprendizaje profundas, considere el uso de la carga de datos Biblioteca ( DALI ) para acelerar la tubería de datos.

Compruebe el NVIDIA® DALI: Operaciones de la documentación para obtener una lista de los programas operativos soportados DALI.

Utilice subprocesos y ejecución paralela

Ops ejecutarse en múltiples hilos de CPU con el tf.config.threading API para ejecutar más rápidamente.

TensorFlow establece automáticamente la cantidad de subprocesos de paralelismo de forma predeterminada. El grupo de subprocesos disponible para ejecutar operaciones de TensorFlow depende de la cantidad de subprocesos de CPU disponibles.

Control de la aceleración máxima en paralelo para una sola op utilizando tf.config.threading.set_intra_op_parallelism_threads . Tenga en cuenta que si ejecuta varias operaciones en paralelo, todas compartirán el grupo de subprocesos disponible.

Si tiene operaciones no bloqueantes independientes (ops sin camino dirigido entre ellos en el gráfico), uso tf.config.threading.set_inter_op_parallelism_threads para ejecutarlas simultáneamente utilizando el grupo de subprocesos disponibles.

Diverso

Cuando se trabaja con modelos más pequeños en las GPU NVIDIA®, se puede establecer tf.compat.v1.ConfigProto.force_gpu_compatible=True a la fuerza de todos los tensores de CPU que deben asignarse en CUDA memoria cubrió para dar un impulso importante para el rendimiento del modelo. Sin embargo, tenga cuidado al usar esta opción para modelos desconocidos / muy grandes, ya que esto podría afectar negativamente el rendimiento del host (CPU).

Mejorar el rendimiento del dispositivo

Siga las mejores prácticas que se detallan aquí y en la guía de optimización de rendimiento de la GPU para optimizar el rendimiento del modelo TensorFlow en el dispositivo.

Si está utilizando NVIDIA GPU, registre la GPU y la utilización de la memoria en un archivo CSV ejecutando:

nvidia-smi
--query-gpu=utilization.gpu,utilization.memory,memory.total,
memory.free,memory.used --format=csv

Configurar el diseño de datos

Cuando trabaje con datos que contienen información del canal (como imágenes), optimice el formato de diseño de datos para preferir los canales en último lugar (NHWC sobre NCHW).

Formatos de datos de canal últimos mejoran Tensor Core utilización y proporcionan mejoras de rendimiento significativas, especialmente en los modelos de convolución cuando se combinan con AMP. Los diseños de datos de NCHW aún pueden ser operados por Tensor Cores, pero introducen una sobrecarga adicional debido a las operaciones de transposición automática.

Se puede optimizar el diseño de datos a preferir diseños NHWC estableciendo data_format="channels_last" para las capas como tf.keras.layers.Conv2D , tf.keras.layers.Conv3D y tf.keras.layers.experimental.preprocessing.RandomRotation .

Uso tf.keras.backend.set_image_data_format para establecer el formato de diseño de datos predeterminado para la API de backend Keras.

Maximiza la caché L2

When working with NVIDIA® GPUs, execute the code snippet below before the training loop to max out the L2 fetch granularity to 128 bytes.

import ctypes

_libcudart = ctypes.CDLL('libcudart.so')
# Set device limit on the current device
# cudaLimitMaxL2FetchGranularity = 0x05
pValue = ctypes.cast((ctypes.c_int*1)(), ctypes.POINTER(ctypes.c_int))
_libcudart.cudaDeviceSetLimit(ctypes.c_int(0x05), ctypes.c_int(128))
_libcudart.cudaDeviceGetLimit(pValue, ctypes.c_int(0x05))
assert pValue.contents.value == 128

Configure GPU thread usage

The GPU thread mode decides how GPU threads are used.

Set the thread mode to gpu_private to make sure that preprocessing does not steal all the GPU threads. This will reduce the kernel launch delay during training. You can also set the number of threads per GPU. Set these values using environment variables.

import os

os.environ['TF_GPU_THREAD_MODE']='gpu_private'
os.environ['TF_GPU_THREAD_COUNT']='1'

Configure GPU memory options

In general, increase the batch size and scale the model to better utilize GPUs and get higher throughput. Note that increasing the batch size will change the model's accuracy so the model needs to be scaled by tuning hyperparameters like the learning rate to meet the target accuracy.

Also, use tf.config.experimental.set_memory_growth to allow GPU memory to grow to prevent all the available memory from being fully allocated to ops that require only a fraction of the memory. This allows other processes which consume GPU memory to run on the same device.

To learn more, check out the Limiting GPU memory growth guidance in the GPU guide to learn more.

Miscellaneous

  • Increase the training mini-batch size (number of training samples used per device in one iteration of the training loop) to the maximum amount that fits without an out of memory (OOM) error on the GPU. Increasing the batch size impacts the model's accuracy—so make sure you scale the model by tuning hyperparameters to meet the target accuracy.

  • Disable reporting OOM errors during tensor allocation in production code. Set report_tensor_allocations_upon_oom=False in tf.compat.v1.RunOptions .

  • For models with convolution layers, remove bias addition if using batch normalization. Batch normalization shifts values by their mean and this removes the need to have a constant bias term.

  • Use TF Stats to find out how efficiently on-device ops run.

  • Use tf.function to perform computations and optionally, enable the jit_compile=True flag ( tf.function(jit_compile=True ). To learn more, go to Use XLA tf.function .

  • Minimize host Python operations between steps and reduce callbacks. Calculate metrics every few steps instead of at every step.

  • Keep the device compute units busy.

  • Send data to multiple devices in parallel.

  • Consider using 16-bit numerical representations , such as fp16 —the half-precision floating point format specified by IEEE—or the Brain floating-point bfloat16 format.

Additional resources

Known limitations

Profiling multiple GPUs on TensorFlow 2.2 and TensorFlow 2.3

TensorFlow 2.2 and 2.3 support multiple GPU profiling for single host systems only; multiple GPU profiling for multi-host systems is not supported. To profile multi-worker GPU configurations, each worker has to be profiled independently. From TensorFlow 2.4 multiple workers can be profiled using the tf.profiler.experimental.client.trace API.

CUDA® Toolkit 10.2 or later is required to profile multiple GPUs. As TensorFlow 2.2 and 2.3 support CUDA® Toolkit versions only up to 10.1, you need to create symbolic links to libcudart.so.10.1 and libcupti.so.10.1 :

sudo ln -s /usr/local/cuda/lib64/libcudart.so.10.2 /usr/local/cuda/lib64/libcudart.so.10.1
sudo ln -s /usr/local/cuda/extras/CUPTI/lib64/libcupti.so.10.2 /usr/local/cuda/extras/CUPTI/lib64/libcupti.so.10.1