Algunos trucos de Pytorch
colegio de cambios
- 29 de noviembre de 2019: actualizó algunas técnicas de diseño de modelos y contenido de aceleración de razonamiento, y agregó un enlace de introducción al ápice,
Además, eliminé TFRecord, ¿se puede usar Pytorch? Recuerdo que no puedo, así que lo eliminé (Indica eliminación: <) - 30 de noviembre de 2019: Significado de Mac complementario, enlace de papel complementario de shufflenetv2
- 2 de diciembre de 2019: el Pytorch que mencioné anteriormente no puede usar TFRecord. Hoy vi una respuesta de https://www.zhihu.com/question/358632497, y estoy en una postura ascendente.
- 23 de diciembre de 2019: agregaron varios artículos científicos populares sobre cuantificación de compresión modelo
- 7 de febrero de 2020: algunas cosas a tener en cuenta fueron extraídas del artículo y se agregaron a la sección de nivel de código
- 30 de abril de 2020:
- Se agregó una copia de seguridad de documentos de GitHub
- Enlaces complementados a la introducción de la capa convolucional y la fusión de la capa BN
- Aquí hay otra explicación. Para los artículos y respuestas de muchos amigos a los que he hecho referencia antes, los enlaces y el resumen de contenido correspondiente no están vinculados juntos. Se estima que algunos amigos harán preguntas cuando lean contenido relacionado, y no pueden preguntarle al autor original. Lo siento profundamente aquí.
- Ajuste algo de contenido e intente corresponder al enlace de referencia
- 18 de mayo de 2020: Agregue algunos consejos sobre Pytorch para guardar la memoria de video. Al mismo tiempo, simplemente ajuste el formato. También encontré un error anterior: la sugerencia de
non_blocking=False debería ser non_blocking=True . - 6 de enero de 2021: ajuste algunas presentaciones en la lectura de datos de imagen.
- 13 de enero de 2021: agregó una estrategia para el razonamiento acelerado. Creo que debería actualizar primero el documento GitHub. La actualización de las respuestas de Zhihu es un poco problemática, y es imposible comparar el cambio de información, por lo que es muy difícil.
- 26 de junio de 2022: El siguiente formato y el acuerdo de contenido se han reajustado, mientras que se han agregado referencias adicionales y algunos de los últimos descubrimientos.
- 20 de junio de 2024: el ajuste simple del formato se complementa con una idea para acelerar la lectura de datos basada en el formato
tar y IterableDataset .
Pytorch acelera
Nota
Documento original: https://www.yuque.com/lart/ugkv9f/ugysgn
Declaración: La mayor parte del contenido proviene de compartir en Zhihu y otros blogs, y solo figura aquí como una colección. Más sugerencias son bienvenidas.
Respuesta de Zhihu (bienvenido a Me gusta):
- La carga de datos de Pytorch DataLoader ocupa la mayor parte del tiempo. ¿Cómo lo resuelven? - Respuesta del artista del pueblo - Zhihu
- Cuando se usa Pytorch, hay demasiados datos establecidos de entrenamiento para llegar a decenas de millones, y ¿qué debo hacer si el dataloader se carga muy lentamente? - Respuesta del artista del pueblo - Zhihu
Pretratamiento se acelera
- Para minimizar las operaciones de preprocesamiento cada vez que lee datos, puede considerar usar algunas operaciones fijas, como
resize , y guardarlas con anticipación, y usarlos directamente durante la capacitación. - Mueva el preprocesamiento a la GPU para acelerar.
- Linux puede usar
NVIDIA/DALI . - Use operaciones de procesamiento de imágenes basadas en tensor.
IO acelera
- MMCV proporciona un soporte relativamente eficiente e integral para la lectura de datos: OpenMMLAB: Análisis de componentes del núcleo MMCV (III): FilEclient
Utilice un procesamiento de imágenes más rápido
-
opencv es generalmente más rápido que PIL .- Tenga en cuenta que la estrategia de carga perezosa de
PIL hace que se vea open que imread de opencv , pero de hecho no carga completamente los datos. Puede llamar al método load() en el objeto devuelto al open para cargar datos manualmente. La velocidad es razonable en este momento.
- Para las lecturas
jpeg , puede probar jpeg4py . - Guarde el gráfico
bmp (reduzca el tiempo de decodificación). - Discusión sobre la velocidad de diferentes bibliotecas de procesamiento de imágenes: ¿Cuál es la diferencia entre el método de implementación y la velocidad de lectura de las diversas funciones IMEAD de Python? - Zhihu
Integre los datos en un solo archivo continuo (reduzca el número de lecturas)
Para lecturas de archivos pequeños a gran escala, se puede guardar como un formato de archivo continuo que se puede leer continuamente. Puede elegir considerar TFRecord (Tensorflow) , recordIO , hdf5 , pth , n5 , lmdb , etc.
-
TFRecord : https://github.com/vahidk/tfrecord - Base de datos
lmdb :- https://github.com/fangyh09/image2lmdb
- https://blog.csdn.net/p_lart/article/details/103208405
- https://github.com/lartpang/pysodtoolbox/blob/master/forbigdataset/imagefolder2lmdb.py
- Implementación basada en el archivo
Tar y IterableDataset
Datos de lectura previa
Realice previamente los datos requeridos para la próxima iteración. Casos de uso:
- Cómo darle el dataloader en Pytorch - Mkfmiku Artículos - Zhihu
- Acelerar los datos de lectura a Pytorch - Artículos sobre Hi - Zhihu
Con memoria
- Cargar directamente en la memoria.
- Lea la imagen y guárdela en un objeto de contenedor fijo.
- MAPE MEMORIA AL DISCO.
Con estado sólido
El disco duro mecánico se reemplaza con un estado sólido NVME. Consulte cómo darle una sangre de pollo en el dataloader en Pytorch - Artículo de Mkfmiku - Zhihu
Estrategias de capacitación
Entrenamiento de baja precisión
En el entrenamiento, se utilizan representaciones de baja precisión ( FP16 o incluso INT8 , red binaria y red de tres valores) en lugar de las representaciones de precisión original ( FP32 ).
Puede ahorrar una cierta cantidad de memoria de video y acelerar, pero tenga cuidado con las operaciones inseguras como la media y la suma.
- Introducción al entrenamiento de precisión mixta:
- Tutorial de entrenamiento de precisión mixto de superficie a profundo
- Soporte de precisión mixta proporcionada por
NVIDIA/Apex .- Pytorch Artifacto imprescindible | Free-Free: Aceleración de precisión híbrida basada en Apex
- Instalación de Pytorch de soluciones de enfermedades difíciles y misceláneas - Artículos de Chen Hanke - Zhihu
- Pytorch1.6 comienza a proporcionar
torch.cuda.amp para admitir precisión mixta.
Un lote más grande
Los lotes más grandes tienden a conducir a un tiempo de entrenamiento más corto en el caso de la época fija. Sin embargo, los lotes grandes enfrentan muchas consideraciones, como la configuración del hiperparameter y el uso de la memoria, que es otra área que ha atraído mucha atención.
- Configuración de hiperparameter
- SGD de minibatch grande y preciso: entrenamiento de Imagenet en 1 hora, papel
- Optimizar el uso de la memoria de video
- Acumulación de gradiente
- Punta de control de gradiente
- Entrenamiento de redes profundas con costo de memoria sublineal, papel
- Operación en el lugar
- BatchNorm activado en el lugar para el entrenamiento optimizado de memoria de DNNS, documentos, código
Nivel de código
Configuración de la biblioteca
- Configuración
torch.backends.cudnn.benchmark = True antes de que el bucle de entrenamiento pueda acelerar el cálculo. Dado que el rendimiento de los algoritmos CUDNN que calculan las convoluciones de diferentes tamaños de núcleos difieren, el AutoTuner puede ejecutar un punto de referencia para encontrar el mejor algoritmo. Se recomienda habilitar esta configuración cuando su tamaño de entrada no cambia con frecuencia. Si el tamaño de la entrada cambia con frecuencia, el AutoTuner deberá ser comparado con demasiada frecuencia, lo que puede dañar el rendimiento. Puede aumentar la velocidad de propagación hacia adelante y hacia atrás en 1.27x a 1.70x. - Use la página para bloquear la memoria, es decir, establecer
pin_memory=True en dataLoader. - Para
num_worker apropiado, se pueden encontrar discusiones detalladas en la Guía de aceleración de Pytorch - Artículos de Yunmeng - Zhihu. - Optimizer.Zero_Grad (set_to_none = false aquí puede reducir
memset huella de la memoria estableciendo model.zero_grad() set_to_none=True y puede mejorar None el rendimiento. Pero esto también cambiará algún comportamiento, lo cual es visible para la documentación. optimizer.zero_grad() memset , None el gradiente se actualizará utilizando la operación "Escribir solo". - Durante la backpropagation, use el modo
eval y use torch.no_grad para desactivar los cálculos de gradiente. - Considere usar el formato de memoria Channels_Last.
- Reemplace
DataParallel con DistributedDataParallel . Para las múltiples GPU, incluso si solo DataParallel un solo nodo, DistributedDataParallel siempre se prefiere porque DistributedDataParallel se aplica a múltiples procesos y crea uno para cada GPU, evitando el bloqueo de intérpretes globales de Python (GIL) y el aumento de la velocidad.
Modelo
- No inicialice ninguna variable no utilizada, porque la inicialización y
forward de Pytorch están separados, y no se inicializará porque no las usa. -
@torch.jit.script , use Pytroch JIT para fusionar operaciones puntuales por punto en un solo núcleo CUDA. Pytorch optimiza el funcionamiento de tensores con grandes dimensiones. Es muy ineficiente hacer demasiadas operaciones en pequeños tensores en Pytorch. Entonces, si es posible, reescribir todas las operaciones de cálculo en lotes puede reducir el consumo y mejorar el rendimiento. Si no puede implementar manualmente operaciones de lotes, entonces TorchScript se puede usar para mejorar el rendimiento de su código. Torchscript es un subconjunto de funciones de Python, pero después de que Pytorch sea verificado por Pytorch, Pytorch puede optimizar automáticamente el código Torchscript para mejorar el rendimiento a través de su compilador justo en el tiempo (JTT). Pero un mejor enfoque es implementar manualmente las operaciones por lotes. - Cuando use FP16 con precisión mixta, establezca un múltiplo de tamaño 8 para todos los diseños arquitectónicos diferentes.
- La capa convolucional antes de BN puede eliminar el sesgo. Porque matemáticamente, el sesgo puede compensarse mediante la resta de Bn. Podemos guardar los parámetros del modelo y la memoria de tiempo de ejecución.
datos
- Establezca el tamaño del lote en un múltiplo de 8 para maximizar el uso de la memoria de GPU.
- Realice operaciones de estilo Numpy tanto como sea posible en la GPU.
- Use
del para liberar la huella de memoria. - Evite la transmisión innecesaria de datos entre diferentes dispositivos.
- Al crear un tensor, especifique el dispositivo directamente, en lugar de crearlo y luego transferirlo al dispositivo de destino.
- Use
torch.from_numpy(ndarray) o torch.as_tensor(data, dtype=None, device=None) , que puede evitar volver a aplicar espacio compartiendo memoria. Para obtener detalles y precauciones, consulte el documento correspondiente. Si los dispositivos de origen y de destino son CPU, torch.from_numpy y torch.as_tensor no copiarán los datos. Si los datos de origen son una matriz Numpy, use torch.from_numpy es más rápido. Si los datos de origen son un tensor con el mismo tipo de datos y tipo de dispositivo, torch.as_tensor puede evitar copiar los datos, que pueden ser una lista, tupla o tensor de Python. - Use la transmisión sin bloqueo, es decir, establecer
non_blocking=True . Esto intenta la conversión asincrónica cuando sea posible, por ejemplo, convertir un tensor de CPU en la memoria de bloqueo de la página en un tensor CUDA.
Optimización del optimizador
- Almacene los parámetros del modelo en una pieza continua de memoria, reduciendo así el tiempo de
optimizer.step() .-
contiguous_pytorch_params
- Uso de bloques de construcción fusionados en APEX
Diseño de modelo
CNN
- Shufflenetv2, papel.
- Los canales de entrada y salida de la capa de convolución son consistentes: cuando el número de canales de características de entrada y salida de la capa de convolución es igual, la Mac (tiempo de consumo de memoria, la abreviatura
memory access cost es MAC ) es la más pequeña, y la velocidad del modelo es la más rápida en este momento en este momento - Reducir la agrupación convolucional: demasiadas operaciones grupales aumentarán la Mac, lo que ralentizará el modelo
- Reducir las ramas del modelo: cuanto menos ramas en el modelo, más rápido es el modelo
- Reduzca las operaciones
element-wise : el consumo de tiempo aportado por las operaciones element-wise es mucho mayor que los valores reflejados en los flops, por lo que las operaciones element-wise deben minimizarse tanto como sea posible. depthwise convolution también tiene las características de los bajos flops y el Mac alto.
Transformador de visión
- TRT-VIT: transformador de visión orientado a tensorrt, papel, interpretación.
- Level de etapa: el bloque de transformador es adecuado para etapas posteriores del modelo, lo que maximiza la compensación entre eficiencia y rendimiento.
- Level de la etapa: el patrón de diseño de la etapa con primero y luego profundo puede mejorar el rendimiento.
- A nivel de bloque: un bloque híbrido de transformador y cuello de botella es más efectivo que un transformador separado.
- A nivel de bloque: el patrón de diseño de bloques global y local ayuda a compensar los problemas de rendimiento.
Ideas generales
- Reduzca la complejidad: por ejemplo, corte y poda del modelo, reduzca las capas del modelo y la escala de parámetros
- Modificar la estructura del modelo: por ejemplo, destilación del modelo y obtener pequeños modelos a través del método de destilación de conocimiento
Acelerar el razonamiento
Mitad precisión y ponderación
Use la representación de baja precisión ( FP16 o incluso INT8 , red binaria y red de tres valores) en inferencia para reemplazar la representación de precisión original ( FP32 ).
-
TensorRT es un motor de inferencia de red neuronal propuesto por NVIDIA, que admite cuantización posterior al entrenamiento de 8 bits. Utiliza un algoritmo de cuantificación de modelo basado en la entropía cruzada para minimizar el grado de diferencia entre las dos distribuciones. - Pytorch1.3 ya ha admitido la función de cuantización, basada en la implementación de Qnnpack, y admite cuantización posterior al entrenamiento, cuantificación dinámica y capacitación en percepción de cuantificación y otras tecnologías.
- Además,
Distiller es una herramienta de optimización de modelos de código abierto basada en Pytorch, y naturalmente admite tecnología cuantitativa en Pytorch. -
NNI de Microsoft integra una variedad de algoritmos de capacitación de percepción cuantitativa y admite múltiples marcos de código abierto como PyTorch/TensorFlow/MXNet/Caffe2
Para obtener más detalles, consulte tres AIS: [charla miscelánea] ¿Cuáles son las herramientas de código abierto disponibles para la cuantificación actual del modelo?
Fusión operacional
- Habilidades de aceleración de razonamiento modelo: Fusión de Bn y Conv Capas - Artículos de XiaoxiaOJiang - Zhihu
- La convergencia de la capa Conv y la capa BN en la etapa de inferencia de red - Artículo de Autocyz - Zhihu
- Pytorch en sí proporciona una funcionalidad similar
Re-parametrización
- Repvgg
- Repvgg | Deje que su convnet al final, la red simple supera el 80% Top1 por primera vez
Análisis de tiempo
- Python viene con varios
profile de análisis de rendimiento, cProfile y hotshot . Los métodos de uso son básicamente los mismos. No es nada más que si el módulo es puro pitón o escrito en C. - Pytorch Profiler es una herramienta que recopila métricas de rendimiento durante la capacitación e inferencia. La API del administrador de contexto de Profiler se puede utilizar para comprender mejor qué operador del modelo es el más caro, verifique su forma de entrada y registros de pila, la actividad del núcleo del dispositivo de estudio y visualizar los registros de ejecución.
Recomendación del proyecto
- Implementar compresión modelo basada en Pytorch:
- Cuantificación: 8/4/2 bits (dorefa), valor de tres valores/binarios (twn/bnn/xnor-net).
- Poda: poda normal, regular y canal para estructuras convolucionales agrupadas.
- Estructura convolucional agrupada.
- BN Fusion para cuantización binaria de características.
Lectura extendida
- La carga de datos de Pytorch DataLoader ocupa la mayor parte del tiempo. ¿Cómo lo resuelven? - Zhihu
- Cuando se usa Pytorch, hay demasiados datos establecidos de entrenamiento para llegar a decenas de millones, y ¿qué debo hacer si el dataloader se carga muy lentamente? - Zhihu
- ¿Cuáles son las trampas/errores en Pytorch? - Zhihu
- Optimización del código de entrenamiento de Pytorch
- 26 segundos de entrenamiento de GPU único CIFAR10, Jeff Dean también le gustan las habilidades de optimización de aprendizaje profundo: artículos sobre el corazón de las máquinas - Zhihu
- Después de capacitar algunas características nuevas en el modelo en línea, ¿por qué el tiempo de predicción de TensorFlow sirve más de 20 veces más lento que el original? - Respuesta de Tzesing - Zhihu
- Compresión del modelo de aprendizaje profundo
- Hoy, ¿se ha acelerado tu modelo? Aquí hay 5 métodos para su referencia (con análisis de código)
- Resumen de las trampas comunes en Pytorch - Artículos de Yu Zhenbo - Zhihu
- Guía de aceleración de Pytorch - Artículos de Yunmeng - Zhihu
- Optimizar la velocidad y la eficiencia de la memoria de Pytorch (2022)
Pytorch guarda memoria de video
Documento original: https://www.yuque.com/lart/ugkv9f/nvffyf
Recopilado de: ¿Cuáles son los consejos para guardar la memoria (memoria de video) en Pytorch? - Zhihu https://www.zhihu.com/question/274635237
Use en el lugar
- Intente habilitar las operaciones que admiten
inplace de forma predeterminada. Por ejemplo, relu puede usar inplace=True . -
batchnorm y algunas funciones de activación específicas se pueden empaquetar en inplace_abn .
Función de pérdida
Eliminar la pérdida al final de cada bucle puede guardar muy poca memoria de video, pero es mejor que nada. Tensor a las mejores prácticas variables y liberadoras de memoria
Mezcla de precisión
Puede ahorrar una cierta cantidad de memoria de video y acelerar, pero tenga cuidado con las operaciones inseguras como la media y la suma.
- Introducción al entrenamiento de precisión mixta:
- Tutorial de entrenamiento de precisión mixto de superficie a profundo
- Soporte de precisión mixta proporcionada por
NVIDIA/Apex .- Pytorch Artifacto imprescindible | Free-Free: Aceleración de precisión híbrida basada en Apex
- Instalación de Pytorch de soluciones de enfermedades difíciles y misceláneas - Artículos de Chen Hanke - Zhihu
- Pytorch1.6 comienza a proporcionar
torch.cuda.amp para admitir precisión mixta.
Administrar operaciones que no requieran backpropagation
- Para las fases hacia adelante que no requieren backpropagation, como períodos de verificación e inferencia, use
torch.no_grad para envolver el código.- Tenga en cuenta que
model.eval() no es igual a torch.no_grad() , consulte la siguiente discusión: 'Model.eval ()' Vs 'con Torch.No_Grad ()'
- Establezca
requires_grad de variables que no necesitan calcular el gradiente a False , de modo que la variable no participe en la propagación hacia atrás del gradiente para reducir el uso de la memoria de gradientes innecesarios. - Elimine la ruta de gradiente que no es necesario calcular:
- Propropagación estocástica: una estrategia de memoria eficiente para capacitar modelos de video, se puede ver la interpretación:
- https://www.yuque.com/lart/papers/xu5t00
- https://blog.csdn.net/p_lart/article/details/124978961
Limpieza de memoria de video
-
torch.cuda.empty_cache() es una versión avanzada de del . El uso de nvidia-smi encontrará que la memoria de video tiene cambios obvios. Sin embargo, el uso máximo de la memoria de video durante el entrenamiento no parece cambiar. Puede intentar: ¿Cómo podemos liberar la memoria caché de memoria GPU? - Puede usar
del para eliminar variables intermedias innecesarias o usar la forma de replacing variables para reducir la ocupación.
Acumulación de gradiente
Divida un batchsize=64 en dos lotes de 32, y después de dos reenviados, hacia atrás una vez. Pero afectará batchnorm y otras capas relacionadas con batchsize .
En la documentación de Pytorch, se menciona un ejemplo de uso de acumulación de gradiente y precisión de mezcla.
Use la tecnología de acumulación de gradiente para acelerar la capacitación distribuida, que se puede utilizar para consultar: [original] [profundo] [Pytorch] DDP Serie 3: Práctico y habilidades - 996 artículos de la generación dorada - Zhihu
Punta de control de gradiente
torch.utils.checkpoint se proporciona en Pytorch. Esto se logra re-ejecutando la propagación hacia adelante en cada ubicación de punto de control durante la propagación de retroceso.
La capacitación en papel de las redes profundas con costo de memoria sublineal se basa en la tecnología de punto de control de gradiente para reducir la memoria de video de O (N) a O (SQRT (N)). Para modelos más profundos, cuanto más memoria guarde este método y no se ralentiza significativamente.
- Análisis del mecanismo de punto de control de Pytorch
- tortch.utils.checkpoint Introducción y fácil de usar
- Una implementación de Pytorch del costo de memoria sublineal, referenciado desde: ¿Cuáles son los consejos para guardar la memoria (memoria de video) en Pytorch? - Respuesta de Lyken - Zhihu
Herramientas relacionadas
- Estos códigos pueden ayudarlo a detectar la memoria de su GPU durante el entrenamiento con Pytorch. https://github.com/oldpan/pytorch-memory-utils
- ¿Solo menos que nvidia-smi? https://github.com/wookayin/gpustat
Referencias
- ¿Cuáles son los consejos para guardar la memoria (memoria de video) en Pytorch? - Respuesta de Zheng Zhedong - Zhihu
- Una breve discusión sobre el aprendizaje profundo: cómo calcular la huella de la memoria de los modelos y las variables intermedias
- Cómo utilizar finamente la memoria de video en Pytorch
- ¿Cuáles son los consejos para guardar la memoria de video en Pytorch? - Respuesta de Chen Hanke - Zhihu
- Análisis del mecanismo de memoria de video de Pytorch - Artículo de Connolly - Zhihu
Otros consejos
Reproducir
Puede seguir capítulos relevantes en el documento.
Operación determinista obligatoria
Evite usar algoritmos no deterministas.
En Pytorch, torch.use_deterministic_algorithms() puede forzar el uso de algoritmos deterministas en lugar de algoritmos no detecterministas, y se lanza un error si se sabe que la operación es no determinista (y sin alternativa determinista).
Establecer semillas de números aleatorios
def seed_torch ( seed = 1029 ):
random . seed ( seed )
os . environ [ 'PYTHONHASHSEED' ] = str ( seed )
np . random . seed ( seed )
torch . manual_seed ( seed )
torch . cuda . manual_seed ( seed )
torch . cuda . manual_seed_all ( seed ) # if you are using multi-GPU.
torch . backends . cudnn . benchmark = False
torch . backends . cudnn . deterministic = True
seed_torch () Referencia de https://www.zdaiot.com/mlframeworks/pytorch/pytorch%E9%9A%8F%E6%9C%BA%E7%A7%8D%E5%AD%90/
Error oculto en dataLoader antes de Pytorch versión 1.9
Los detalles específicos muestran que el 95% de las personas todavía están cometiendo errores de Pytorch - Artículos de casualidad - Zhihu
Para soluciones, consulte la documentación:
def seed_worker ( worker_id ):
worker_seed = torch . initial_seed () % 2 ** 32
numpy . random . seed ( worker_seed )
random . seed ( worker_seed )
DataLoader (..., worker_init_fn = seed_worker )