Skip to main content
  • Place orders quickly and easily
  • View orders and track your shipping status
  • Enjoy members-only rewards and discounts
  • Create and access a list of your products

Técnicas de otimização para treinamento do CheXNet no Dell C4140 com GPUs NVIDIA V100

Summary: Práticas recomendadas para obter o desempenho máximo em treinamento ampliado distribuído do CheXNet utilizando GPUs Nvidia V100 SXM2 em servidores Dell EMC C4140.

This article applies to   This article does not apply to 

Symptoms

O artigo foi escrito por Rakshith Vasudev e John Lockmanm – Laboratório de inovação em IA e HPC em outubro de 2019

Cause

  -

Resolution

Como mencionado anteriormente, o CheXNet é um modelo de assistente de radiologia de IA que usa o DenseNet para identificar até 14 patologias em uma imagem específica de raios X do tórax. Várias abordagens foram exploradas para ampliar o treinamento de um modelo que poderia ter um desempenho tão bom ou melhor do que o CheXNet-121 original. O ResNet-50 se mostrou promissor tanto em escalabilidade quanto em maior precisão de treinamento (AUROC positivo). Os autores demonstraram a escalabilidade em sistemas de CPU. No entanto, estamos interessados em explorar o paralelismo das GPUs para acelerar o processo de treinamento. Neste artigo, descrevemos as práticas recomendadas para obter o desempenho máximo em treinamento ampliado distribuído do CheXNet utilizando GPUs Nvidia V100 SXM2 em servidores Dell EMC C4140. O Dell EMC PowerEdge C4140 oferece densidade e desempenho com quatro GPUs Nvidia V100 na configuração SXM2.


 

Configuração do hardware: Configuração do software:
  • 4x PowerEdge C4140
  • 4x Nvidia V100 de 32 GB SXM2
  • 2x CPU Intel(R) Xeon(R) Gold 6148 de 20 núcleos a 2,40 GHz
  • 384 GB de RAM, DDR4 2666 MHZ
  • 1 Mellanox EDR HCA
  • Sistema de arquivos Lustre
  • Estrutura do deep learning: tensorflow-gpu
  • Versão da estrutura: 1.12.0
  • Versão do Horovod: 0.16.4
  • Versão do MPI: 4.0.0 com suporte a cuda e ucx
  • Versão do CUDA: 10.1.105
  • Versão do CUDNN: 7.6.0
  • Versão do NCCL: 2.4.7
  • Versão do Python: 3.6.8
  • SO e versão: RHEL 7.4


 


O pipeline de dados é essencial para obter o máximo desempenho dos aceleradores:



 

O que é a tf data, por que você deve usá-la?

 

À medida que novos dispositivos de computação (como GPUs e TPUs) possibilitam o treinamento de redes neurais a uma taxa cada vez mais rápida, o processamento da CPU está propenso a se tornar o gargalo. A API tf.data fornece aos usuários componentes básicos para projetar pipelines de entrada que utilizam efetivamente a CPU, otimizando cada etapa do processo ETL.

 

Para executar uma etapa de treinamento, primeiro você deve extrair e transformar os dados de treinamento e, em seguida, inseri-los em um modelo em execução em um acelerador. No entanto, em uma implementação síncrona simples, enquanto a CPU está preparando os dados, o acelerador fica ocioso. Por outro lado, enquanto o acelerador está treinando o modelo, a CPU fica ociosa. O tempo da etapa de treinamento é, portanto, a soma do tempo de pré-processamento da CPU e do tempo de treinamento do acelerador

 

A criação do pipeline coincide com o pré-processamento e a execução do modelo de uma etapa de treinamento. Enquanto o acelerador está executando a etapa de treinamento N, a CPU está preparando os dados para a etapa N+1. Isso reduz ao máximo (em vez de aumentar) o tempo da etapa do treinamento e o tempo necessário para extrair e transformar os dados.

 

Sem a criação de pipeline, a CPU e a GPU/TPU ficam ociosas em grande parte do tempo:

SLN318898_en_US__1Sequantial execution
Figura 1: A execução sequencial frequentemente deixa a GPU ociosa

 

Com a criação de pipeline, o tempo de inatividade diminui significativamente:

SLN318898_en_US__2Pipelining overlaps
Figura 2: A criação do pipeline coincide com a utilização da CPU e da GPU, maximizando a utilização da GPU

 

A API tf.data fornece um mecanismo de criação de pipeline de software por meio da transformação tf.data.Dataset.prefetch, que pode ser usada para separar o momento em que os dados são produzidos do momento em que são consumidos. Especificamente, a transformação usa um thread de segundo plano e um buffer interno para pré-buscar elementos do conjunto de dados de entrada antes do momento em que eles são solicitados.

 

Você pode encontrar mais informações em: https://www.tensorflow.org/guide/performance/datasets

 

Ao seguir as diretrizes fornecidas pelo tensorflow, você pode obter um pipeline de dados semelhante a este (abordagem antiga):
https://github.com/dellemc-hpc-ai/code-examples/blob/master/cheXNet-snippets/old_approach.py

 

Nesta abordagem, também conhecida como a abordagem antiga, o pipeline da tf data faz o seguinte (supondo que o conjunto de dados de raios X do tórax seja uma sequência de TFRecords):

 

  1. Obtém a lista absoluta de nomes de arquivos.
  2. Cria um conjunto de dados a partir da lista de nomes de arquivos usando TFRecordDataset()
  3. Cria um novo conjunto de dados que carrega e formata as imagens ao processá-las antecipadamente.
  4. Fragmenta o conjunto de dados.
  5. Mistura o conjunto de dados durante o treinamento.
  6. Repete o conjunto de dados.
  7. Coloca o conjunto de dados em um lote.
  8. Pré-busca o conjunto de dados para o tamanho do lote.


 

No entanto, este não é o código mais eficaz. Ele causa paralisações e utilizações frequentes de 0% da gpu. Basicamente, ele não utiliza os aceleradores com eficiência.

Para configurar corretamente o pipeline da tf data, seguimos a abordagem adotada especificamente pelos modelos oficiais do tensorflow, a mesma do ResNet.  A diferença entre a abordagem antiga e a nova é a forma como o pipeline de dados é configurado antes de ser inserido no modelo.

 

Veja como é a nova abordagem:
https://github.com/dellemc-hpc-ai/code-examples/blob/master/cheXNet-snippets/new_approach.py

 

A abordagem de modelos oficial do TensorFlow, também conhecida como nova abordagem, é a seguinte:

 

  1. Obtém a lista absoluta de nomes de arquivos.
  2. Cria um conjunto de dados a partir da lista de nomes de arquivos usando from_tensor_slices()
  3. A fragmentação é feita antecipadamente.
  4. O conjunto de dados é misturado durante o treinamento.
  5. O conjunto de dados é, então, intercalado paralelamente, que significa intercalar e processar vários arquivos (definido por cycle_length) para transformá-los para criar o conjunto de dados TFRecord.
  6. O conjunto de dados é então pré-buscado. O buffer_size define quantos registros são pré-buscados, o que geralmente é o mini batch_size do trabalho.
  7. O conjunto de dados é misturado novamente. Os detalhes dessa mistura são controlados por buffer_size.
  8. O conjunto de dados é repetido.  Repete o conjunto de dados até num_epochs treinar.
  9. O conjunto de dados é submetido a map_and_batch() simultâneos, que analisam os arquivos de registro tf, pré-processam a imagem e inserem os arquivos em lote.
  10. A imagem pré-processada está pronta como um conjunto de dados e é pré-buscada novamente.


 

Esta é uma comparação do desempenho das abordagens antiga e nova, usando os modelos TF oficiais.

SLN318898_en_US__3image(12053)
Figura 3: Com a nova abordagem, é possível obter um dimensionamento quase linear.

 

Como pode-se perceber, há um impacto significativo no desempenho e não há nenhum dimensionamento com a abordagem antiga. As GPUs frequentemente são pouco utilizadas ou não são utilizadas, e o desempenho fica estagnado. Tornar a computação mais eficiente em uma GPU significa tornar a computação mais eficiente em várias GPUs em vários nós, se a comunicação for bem tratada.
Na nova abordagem, as CPUs realizam o pré-processamento paralelamente, pré-buscam os dados processados na memória e fazem o trabalho pesado de multiplicação de matriz com comunicação rápida. Isso torna essa nova abordagem mais atraente para ser utilizada em vários nós.


 


Outras técnicas a serem avaliadas para alcançar o desempenho ideal:



 

Ter o ambiente correto é importante:

 

O ambiente que executa seus trabalhos é tão importante quanto seus trabalhos. Ter as bibliotecas e os módulos certos é importante, pois eles afetarão o desempenho do treinamento. Além disso, ter as bibliotecas mais recentes relacionadas ao CUDA pode ajudar a melhorar o desempenho.

Siga este tutorial de instalação, caso você não tenha um ambiente de trabalho definido.



 

Uso dos parâmetros de vinculação corretos para MPI:

 

MPI é uma biblioteca de comunicação que ajuda o horovod a distribuir trabalhos. Diferentes opções de parâmetros de vinculação e mapeamento foram exploradas e os melhores parâmetros para o C4140 foram o mapeamento por soquete. A configuração recomendada é a seguinte:
mpirun --map-by socket -np x python pyfile.py --pyoptions



 

Certifique-se de que um processo atue em uma GPU:

 

Se houver vários processos funcionando em uma GPU, eles podem competir por recursos de GPU, consumindo memória de GPU e deixando de incluir mais imagens por lote, isso faz com que o desempenho da GPU atinja o limite. O TensorFlow 1.13.1 foi considerado, mas ele apresentava algum tipo de falha. Ele estava iniciando mais de um processo por GPU.


 

Em resumo:

  • A configuração correta do pipeline de dados é essencial para ter ganhos de desempenho.
  • A configuração do ambiente correto contribui para melhorar o desempenho.
  • O uso dos parâmetros de vinculação corretos para MPI ajuda a melhorar o desempenho.
  • Defina o perfil das GPUs e corrija os respectivos gargalos quando elas não forem totalmente utilizadas.


 


Affected Products

High Performance Computing Solution Resources, Poweredge C4140