Alguns truques de pytorch
Changelog
- 29 de novembro de 2019: Atualizou algumas técnicas de design de modelo e conteúdo de aceleração de raciocínio e adicionou um link de introdução ao ápice,
Além disso, eu excluí tfrecord, pode ser usado pytorch? Lembro que não posso, então eu apaguei (Indica exclusão: <) - 30 de novembro de 2019: significado suplementar de Mac, link de papel suplementar Shufflenetv2
- 2 de dezembro de 2019: O Pytorch que mencionei anteriormente não pode usar o Tfrecord. Hoje eu vi uma resposta em https://www.zhihu.com/question/358632497, e estou em uma postura crescente.
- 23 de dezembro de 2019: Adicionado vários artigos científicos populares sobre quantificação de compressão de modelo
- 7 de fevereiro de 2020: Algumas coisas a serem observadas foram extraídas do artigo e adicionadas à seção de nível de código
- 30 de abril de 2020:
- Adicionado um backup de documento do GitHub
- Links suplementados para a introdução de camada convolucional e fusão da camada BN
- Aqui está outra explicação. Para os artigos e respostas de muitos amigos que me referenciei antes, os links e o resumo do conteúdo correspondente não estão vinculados. Estima -se que alguns amigos façam perguntas ao ler conteúdo relacionado e não podem perguntar ao autor original. Lamento profundamente aqui.
- Ajuste algum conteúdo e tente corresponder ao link de referência
- 18 de maio de 2020: Adicione algumas dicas sobre Pytorch para salvar a memória de vídeo. Ao mesmo tempo, basta ajustar o formato. Também encontrei um erro anterior:
non_blocking=False deveria ser non_blocking=True . - 6 de janeiro de 2021: Ajuste algumas introduções nos dados da imagem de leitura.
- 13 de janeiro de 2021: adicionou uma estratégia para o raciocínio acelerado. Acho que devo atualizar o documento do GitHub primeiro. A atualização do Zhihu Answers é um pouco problemática e é impossível comparar a mudança de informação, por isso é muito difícil.
- 26 de junho de 2022: O seguinte formato e arranjo de conteúdo foram reformulados, enquanto referências adicionais e algumas das últimas descobertas foram adicionadas.
- 20 de junho de 2024: O ajuste simples do formato é complementado com uma idéia para acelerar a leitura de dados com base no formato
tar e IterableDataset .
Pytorch acelera
Observação
Documento original: https://www.yuque.com/lart/ugkv9f/ugysgn
Declaração: A maior parte do conteúdo vem do compartilhamento em Zhihu e outros blogs e só é listado aqui como uma coleção. Mais sugestões são bem -vindas.
Resposta Zhihu (bem -vindo a curtir):
- O carregamento de dados do Pytorch Dataloader leva a maior parte do tempo. Como vocês resolvem isso? - Resposta do Artista Popular - Zhihu
- Ao usar o Pytorch, existem muitos dados do conjunto de treinamento para atingir dezenas de milhões e o que devo fazer se o Dataloader carregar muito lentamente? - Resposta do Artista Popular - Zhihu
O pré -tratamento acelera
- Para minimizar as operações de pré -processamento toda vez que você lê dados, considere usar algumas operações fixas, como
resize e salvá -las com antecedência e usá -las diretamente durante o treinamento. - Mova o pré -processamento para a GPU para acelerar.
- O Linux pode usar
NVIDIA/DALI . - Use operações de processamento de imagem baseadas em tensoras.
Io acelerar
- O MMCV fornece suporte relativamente eficiente e abrangente para a leitura de dados: OpenMmlab: MMCV Core Component Análise (III): FileClient
Use um processamento de imagem mais rápido
-
opencv é geralmente mais rápido que PIL .- Observe que a estratégia de carregamento preguiçosa do
PIL faz com que pareça open que imread do opencv , mas na verdade não carrega completamente os dados. Você pode chamar o método load() no objeto retornado por open para carregar dados manualmente. A velocidade é razoável neste momento.
- Para lê
jpeg , você pode experimentar jpeg4py . - Salve o gráfico
bmp (reduza o tempo de decodificação). - Discussão sobre a velocidade de diferentes bibliotecas de processamento de imagens: qual é a diferença entre o método de implementação e a velocidade de leitura das várias funções imreadas do Python? - Zhihu
Integrar dados em um único arquivo contínuo (reduza o número de leituras)
Para leituras de pequenos arquivos em larga escala, ele pode ser salvo como um formato de arquivo contínuo que pode ser lido continuamente. Você pode optar por considerar TFRecord (Tensorflow) , recordIO , hdf5 , pth , n5 , lmdb , etc.
-
TFRecord : https://github.com/vahidk/tfrecord - Banco de dados
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
- Implementação com base no arquivo
Tar e IterableDataset
Dados pré-leitura
Pré-lida os dados necessários para a próxima iteração. Casos de uso:
- Como dar a você o Dataloader em Pytorch - Mkfmiku Artigos - Zhihu
- Acelere os dados de leitura para Pytorch - Artigos em Hi - Zhihu
Com memória
- Carregar diretamente na memória.
- Leia a imagem e salve -a em um objeto de contêiner fixo.
- Mapeie a memória para o disco.
Com estado sólido
O disco rígido mecânico é substituído pelo estado sólido NVME. Consulte como lhe dar um sangue de frango no Dataloader em Pytorch - Artigo de Mkfmiku - Zhihu
Estratégias de treinamento
Treinamento de baixa precisão
No treinamento, são usadas representações de baixa precisão ( FP16 ou mesmo INT8 , rede binária e rede de três valores) em vez das representações de precisão original ( FP32 ).
Ele pode salvar uma certa quantidade de memória de vídeo e acelerar, mas tenha cuidado com operações inseguras, como média e soma.
- Introdução ao treinamento de precisão mista:
- Tutorial de treinamento de precisão mista de raso a profundo
- Suporte de precisão mista fornecida pela
NVIDIA/Apex .- Pytorch Artefato obrigatório | Aceleração de precisão híbrida baseada em jejum: Aceleração híbrida baseada em ápice
- Instalação de Pytorch de soluções de doenças difíceis e diversas - artigos de Chen Hanke - Zhihu
- Pytorch1.6 começa a fornecer
torch.cuda.amp para suportar precisão mista.
Um lote maior
Lotes maiores tendem a levar a um tempo de treinamento mais curto no caso de época fixa. No entanto, lotes grandes enfrentam muitas considerações, como configuração de hiperparâmetro e uso de memória, que é outra área que atraiu muita atenção.
- Configurações de hiperparâmetro
- SGD de minibatch preciso e preciso: treinamento de imagenet em 1 hora, papel
- Otimize o uso da memória de vídeo
- Acumulação de gradiente
- Ponto de verificação de gradiente
- Treinamento de redes profundas com custo de memória sublinear, papel
- Operação no local
- BatchNorm ativado no local para treinamento otimizado para a memória de DNNs, papéis, código
Nível de código
Configurações da biblioteca
- Configurando
torch.backends.cudnn.benchmark = True antes que o loop de treinamento possa acelerar o cálculo. Como o desempenho dos algoritmos CUDNN que calculam convoluções de diferentes tamanhos do kernel diferem, o automóvel pode executar uma referência para encontrar o melhor algoritmo. Recomenda -se ativar essa configuração quando o tamanho da entrada não muda com frequência. Se o tamanho da entrada mudar com frequência, o AutoTuner precisará ser comparado com muita frequência, o que pode prejudicar o desempenho. Pode aumentar a velocidade de propagação para frente e para trás em 1,27x para 1,70x. - Use a página para bloquear a memória, ou seja, defina
pin_memory=True no Dataloader. - Para
num_worker apropriado, discussões detalhadas podem ser encontradas no Pytorch Speedup Guide - Artigos de Yunmeng - Zhihu. - otimizer.Zero_Grad (set_to_none = false aqui Você pode reduzir a pegada de
memset definindo model.zero_grad() set_to_none=True None pode melhorar moderadamente o desempenho. optimizer.zero_grad() isso também mudará algum memset , que é visível para a documentação. None gradiente será atualizado usando a operação "Escreva apenas". - Durante a retropropagação, use o modo
eval e use torch.no_grad para desativar os cálculos do gradiente. - Considere usar o formato de memória canais_last.
- Substitua
DataParallel pelo DistributedDataParallel . Para Multi-GPUs, mesmo que DataParallel apenas um nó único, DistributedDataParallel é sempre preferido porque DistributedDataParallel é aplicado a vários processos e cria um para cada GPU, ignorando o bloqueio do entreteter global do Python (GIL) e o aumento da velocidade.
Modelo
- Não inicialize variáveis não utilizadas, porque a inicialização e
forward de Pytorch são separadas, e elas não serão inicializadas porque você não as usa. -
@torch.jit.script , use o pytroch jit para fundir operações ponto a ponto em um único kernel CUDA. Pytorch otimiza a operação de tensores com grandes dimensões. É muito ineficiente fazer muitas operações em pequenos tensores em Pytorch. Portanto, se possível, reescrever todas as operações de cálculo em lotes pode reduzir o consumo e melhorar o desempenho. Se você não puder implementar manualmente as operações em lote, o TorchScript poderá ser usado para melhorar o desempenho do seu código. O TorchScript é um subconjunto de funções Python, mas depois que o Pytorch é verificado por Pytorch, o Pytorch pode otimizar automaticamente o código do TorchScript para melhorar o desempenho por meio de seu compilador Just In Time (JTT). Mas uma abordagem melhor é implementar manualmente as operações em lote. - Ao usar o FP16 com precisão mista, defina um múltiplo do tamanho 8 para todos os diferentes projetos arquitetônicos.
- A camada convolucional antes do BN pode remover o viés. Porque matematicamente, o viés pode ser compensado por meio da subtração do BN. Podemos salvar parâmetros do modelo e memória de tempo de execução.
dados
- Defina o tamanho do lote como um múltiplo de 8 para maximizar o uso da memória da GPU.
- Realize operações no estilo Numpy o máximo possível na GPU.
- Use
del para liberar a pegada de memória. - Evite a transmissão desnecessária de dados entre diferentes dispositivos.
- Ao criar um tensor, especifique o dispositivo diretamente, em vez de criá -lo e transferi -lo para o dispositivo de destino.
- Use
torch.from_numpy(ndarray) ou torch.as_tensor(data, dtype=None, device=None) , o que pode evitar reaplicar o espaço compartilhando a memória. Para detalhes e precauções, consulte o documento correspondente. Se os dispositivos de origem e destino forem CPUs, torch.from_numpy e torch.as_tensor não copiarão os dados. Se os dados de origem forem uma matriz Numpy, use torch.from_numpy é mais rápido. Se os dados de origem forem um tensor com o mesmo tipo de dados e tipo de dispositivo, torch.as_tensor poderá evitar copiar os dados, que podem ser uma lista, tupla ou tensor do Python. - Use a transmissão não bloqueadora, ou seja, defina
non_blocking=True . Isso tenta a conversão assíncrona sempre que possível, por exemplo, convertendo um tensor de CPU na memória de bloqueio da página em um tensor de Cuda.
Otimização do otimizador
- Armazene os parâmetros do modelo em uma peça contínua de memória, reduzindo assim o tempo do
optimizer.step() .-
contiguous_pytorch_params
- Usando blocos de construção fundidos no ápice
Design de modelo
CNN
- Shufflenetv2, papel.
- Os canais de entrada e saída da camada de convolução são consistentes: quando o número de canais de recurso de entrada e saída da camada de convolução é igual, o MAC (tempo de consumo de acesso à memória,
memory access cost A abreviação é MAC ) é a menor e a velocidade do modelo é a mais rápida neste momento - Reduza o agrupamento convolucional: muitas operações de grupo aumentarão o Mac, o que desacelerará o modelo
- Reduza as filiais do modelo: quanto menos ramificações no modelo, mais rápido será o modelo
- Reduzir operações
element-wise : o consumo de tempo trazido pelas operações element-wise é muito maior do que os valores refletidos nos flops, portanto as operações element-wise devem ser minimizadas o máximo possível. depthwise convolution também tem as características de baixos flops e Mac alto.
Transformador de visão
- TRT-VIT: Transformador de visão orientado para tensorrt, papel, interpretação.
- Nível de estágio: o bloco de transformadores é adequado para estágios posteriores do modelo, que maximiza a troca entre eficiência e desempenho.
- Nível de estágio: o padrão de design de estágio com raso primeiro e depois profundo pode melhorar o desempenho.
- Nível do bloco: Um bloco híbrido de transformador e gargalo é mais eficaz do que um transformador separado.
- Nível de bloco: o padrão de design de blocos global e então local ajuda a compensar problemas de desempenho.
Idéias gerais
- Reduza a complexidade: por exemplo, corte e poda de modelo, reduza as camadas do modelo e a escala de parâmetros
- Modifique a estrutura do modelo: por exemplo, destilação de modelos e obtenha pequenos modelos através do método de destilação de conhecimento
Acelerar o raciocínio
Meia precisão e ponderação
Use representação de baixa precisão ( FP16 ou mesmo INT8 , rede binária e rede de três valores) em inferência para substituir a representação da precisão original ( FP32 ).
-
TensorRT é um mecanismo de inferência de rede neural proposto pela NVIDIA, que suporta quantização pós-treinamento de 8 bits. Ele usa um algoritmo de quantização de modelo baseado em entropia cruzado para minimizar o grau de diferença entre as duas distribuições. - O Pytorch1.3 já apoiou a função de quantização, com base na implementação do QNNPACK, e suporta o treinamento pós-treinamento, quantização dinâmica e treinamento de percepção de quantização e outras tecnologias.
- Além disso,
Distiller é uma ferramenta de otimização de modelo de código aberto baseado em Pytorch e suporta naturalmente a tecnologia quantitativa em Pytorch. -
NNI da Microsoft integra uma variedade de algoritmos de treinamento quantitativo de percepção e suporta várias estruturas de código aberto, como PyTorch/TensorFlow/MXNet/Caffe2
Para mais detalhes, consulte três AIs: [conversa diversa] Quais são as ferramentas de código aberto disponíveis para a quantificação atual do modelo?
Fusão operacional
- Modelo Raciocínio Habilidades de Aceleração: Fusão de BN e Conv Camadas - Artigos de Xiaoxiaojiang - Zhihu
- A convergência da camada de convivência e da camada BN na fase de inferência da rede - artigo da AutoCyz - Zhihu
- O próprio Pytorch fornece funcionalidade semelhante
Re-parametrização
- Repvgg
- Repvgg | Deixe seu convnet até o fim, a rede simples excede 80% TOP1 pela primeira vez
Análise de tempo
- O Python vem com vários
profile de análise de desempenho, cProfile e hotshot . Os métodos de uso são basicamente os mesmos. Não é nada mais do que se o módulo é puro python ou escrito em C. - O Pytorch Profiler é uma ferramenta que coleta métricas de desempenho durante o treinamento e a inferência. A API do Profiler's Context Manager pode ser usada para entender melhor qual operador de modelo é mais caro, verifique sua forma de entrada e registros de pilha, atividade do kernel do dispositivo de estudo e visualize registros de execução.
Recomendação do projeto
- Implementar compactação de modelo com base em Pytorch:
- Quantificação: bits 8/4/2 (Dorefa), valor de três valores/binário (TWN/BNN/XNOR-NET).
- A poda: poda normal de canal regular para estruturas convolucionais agrupadas.
- Estrutura convolucional agrupada.
- Fusão BN para quantização binária de recursos.
Leitura estendida
- O carregamento de dados do Pytorch Dataloader leva a maior parte do tempo. Como vocês resolvem isso? - Zhihu
- Ao usar o Pytorch, existem muitos dados do conjunto de treinamento para atingir dezenas de milhões e o que devo fazer se o Dataloader carregar muito lentamente? - Zhihu
- Quais são as armadilhas/bugs em Pytorch? - Zhihu
- Otimizando o código de treinamento Pytorch
- 26 segundos Treinamento de GPU único Cifar10, Jeff Dean também gosta das habilidades de otimização de aprendizado profundo - artigos sobre o coração das máquinas - Zhihu
- Depois de treinar alguns novos recursos no modelo on -line, por que o tempo de previsão do Tensorflow serve mais de 20 vezes mais lento que o original? - Resposta de Tzesing - Zhihu
- Compressão do modelo de aprendizado profundo
- Hoje, seu modelo acelerou? Aqui estão 5 métodos para sua referência (com análise de código)
- Resumo das armadilhas comuns em Pytorch - Artigos de Yu Zhenbo - Zhihu
- Guia de aceleração de Pytorch - Artigos de Yunmeng - Zhihu
- Otimize a velocidade e a eficiência da memória de Pytorch (2022)
Pytorch salva a memória de vídeo
Documento original: https://www.yuque.com/lart/ugkv9f/nvffyf
Coletado de: Quais são as dicas para salvar memória (memória de vídeo) em Pytorch? - Zhihu https://www.zhihu.com/question/274635237
Use no local
- Tente habilitar operações que suportem
inplace por padrão. Por exemplo, relu pode usar inplace=True . -
batchnorm e algumas funções de ativação específicas podem ser empacotadas em inplace_abn .
Função de perda
Excluir a perda no final de cada loop pode salvar muito pouca memória de vídeo, mas é melhor que nada. Tensor para as melhores práticas variáveis e de libertação de memória
Mistura de precisão
Ele pode salvar uma certa quantidade de memória de vídeo e acelerar, mas tenha cuidado com operações inseguras, como média e soma.
- Introdução ao treinamento de precisão mista:
- Tutorial de treinamento de precisão mista de raso a profundo
- Suporte de precisão mista fornecida pela
NVIDIA/Apex .- Pytorch Artefato obrigatório | Aceleração de precisão híbrida baseada em jejum: Aceleração híbrida baseada em ápice
- Instalação de Pytorch de soluções de doenças difíceis e diversas - artigos de Chen Hanke - Zhihu
- Pytorch1.6 começa a fornecer
torch.cuda.amp para suportar precisão mista.
Gerenciar operações que não requerem retropropagação
- Para fases para a frente que não requerem retropropagação, como períodos de verificação e inferência, use
torch.no_grad para envolver o código.- Observe que
model.eval() não é igual a torch.no_grad() , consulte a seguinte discussão: 'Model.eval ()' vs 'com Torch.no_grad ()'
- Defina
requires_grad de variáveis que não precisam calcular o gradiente como False , para que a variável não participe da propagação atrasada do gradiente para reduzir o uso da memória de gradientes desnecessários. - Remova o caminho do gradiente que não precisa ser calculado:
- Backpropagation estocástico: uma estratégia eficiente em memória para treinar modelos de vídeo, a interpretação pode ser vista:
- https://www.yuque.com/lart/papers/xu5t00
- https://blog.csdn.net/p_lart/article/details/124978961
Limpeza de memória de vídeo
-
torch.cuda.empty_cache() é uma versão avançada do del . O uso nvidia-smi descobrirá que a memória de vídeo tem alterações óbvias. No entanto, o uso máximo de memória de vídeo durante o treinamento não parece mudar. Você pode tentar: como podemos lançar o cache de memória da GPU? - Você pode usar
del para excluir variáveis intermediárias desnecessárias ou usar a forma de replacing variables para reduzir a ocupação.
Acumulação de gradiente
Divida um batchsize=64 em dois lotes de 32 e após dois encaminhamento, para trás uma vez. Mas isso afetará batchnorm e outras camadas relacionadas ao batchsize .
Na documentação de Pytorch, é mencionado um exemplo de acumulação de gradiente e precisão de mistura.
Use a tecnologia de acumulação de gradiente para acelerar o treinamento distribuído, que pode ser usado para se referir a: [Original] [Deep] [Pytorch] DDP Series 3: Practical and Skills - 996 Artigos da geração de ouro - Zhihu
Ponto de verificação de gradiente
torch.utils.checkpoint é fornecido em Pytorch. Isso é conseguido reexecionar a propagação direta em cada local de verificação durante a retropropagação.
O treinamento em papel nas redes profundas com custo de memória sublinear é baseado na tecnologia do ponto de verificação do gradiente para reduzir a memória de vídeo de O (n) para O (SQRT (N)). Para modelos mais profundos, mais a memória esse método salva e não diminui significativamente.
- Análise do mecanismo de ponto de verificação de pytorch
- Torch.utils.Checkpoint Introdução e fácil de usar
- Uma implementação de Pytorch do custo da memória sublinear, referenciado de: Quais são as dicas para salvar memória (memória de vídeo) em Pytorch? - Resposta de Lyken - Zhihu
Ferramentas relacionadas
- Esses códigos podem ajudá -lo a detectar sua memória da GPU durante o treinamento com o Pytorch. https://github.com/oldpan/pytorch-memory-utils
- Apenas menos de Nvidia-Smi? https://github.com/wookayin/gpustat
Referências
- Quais são as dicas para salvar memória (memória de vídeo) em Pytorch? - Resposta de Zheng Zhedong - Zhihu
- Uma breve discussão sobre aprendizado profundo: como calcular a pegada de memória de modelos e variáveis intermediárias
- Como utilizar finamente a memória de vídeo em Pytorch
- Quais são as dicas para salvar a memória de vídeo em Pytorch? - Resposta de Chen Hanke - Zhihu
- Análise do mecanismo de memória de vídeo pytorch - Artigo de Connolly - Zhihu
Outras dicas
Reproduzir
Você pode seguir os capítulos relevantes no documento.
Operação determinística obrigatória
Evite usar algoritmos não -determinísticos.
Em Pytorch, torch.use_deterministic_algorithms() pode forçar o uso de algoritmos determinísticos em vez de algoritmos não -determinísticos, e um erro for lançado se a operação for conhecida por ser não determinística (e nenhuma alternativa determinística).
Definir sementes de números aleatórios
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 () Referência de https://www.zdaiot.com/mlframeworks/pytorch/pytorch%E9%9a%8f%E6%9c%Ba%E7%A7%8D%E5%AD%90/
Bug oculto no Dataloader antes do Pytorch versão 1.9
Os detalhes específicos mostram que 95% das pessoas ainda estão cometendo erros de pytorch - Artigos de Serendipity - Zhihu
Para soluções, consulte a documentação:
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 )