Notícias portuguesas
Mais recente
IA e Tecnologia

Por dentro do cuda-convnet: camadas do AlexNet em duas GPUs e a era ImageNet

Detalhe ilustrativo do die de um processador, não da GPU NVIDIA discutida no artigo.
Detalhe ilustrativo do die de um processador, não da GPU NVIDIA discutida no artigo.

O marco alcançado pelo AlexNet em 2012 apoiou-se na engenharia de GPUs de baixo nível (cuda-convnet), numa arquitetura dividida entre duas GPUs, e desencadeou diretamente uma corrida rápida por modelos de visão computacional mais profundos e eficientes.

1. Como o cuda-convnet funcionava por dentro

Antes de a NVIDIA criar a cuDNN, Alex Krizhevsky escreveu o cuda-convnet diretamente em CUDA C++ para extrair a velocidade máxima das primeiras GPUs com arquitetura Fermi (a GTX 580). As bibliotecas modernas normalmente desdobram convoluções em enormes multiplicações de matrizes (im2col), o que consome quantidades imensas de memória. Como cada GTX 580 tinha apenas 3 GB de VRAM, Krizhevsky desenvolveu rotinas diretas para GPU que economizavam memória.

  • Organização da memória orientada a lotes (CHWN). Os frameworks modernos adotam por padrão NCHW (Lote, Canais, Altura, Largura), que coloca todos os pixels de uma única imagem lado a lado na memória. Krizhevsky armazenava os tensores na ordem CHWN, deixando a dimensão do lote (N) por último. Quando 32 threads da GPU em um warp processavam 32 imagens diferentes exatamente na mesma posição de pixel, suas leituras de memória eram totalmente contíguas (coalescidas), maximizando a largura de banda da VRAM.
  • Divisão em blocos na memória compartilhada. Ler a VRAM global leva centenas de ciclos de clock, enquanto a memória compartilhada no chip (apenas 48 KB por Streaming Multiprocessor na GTX 580) leva somente alguns ciclos. Os blocos de threads carregavam pequenas regiões 2D de pixels das imagens e pesos dos filtros na memória compartilhada, calculando dezenas de produtos escalares antes de gravar os resultados finais de volta na VRAM.
  • Reutilização de registradores no nível do warp. Krizhevsky atribuía a cada bloco de threads o cálculo simultâneo de um bloco de pixels de saída para vários filtros. Mantendo os pesos dos filtros nos rápidos registradores da GPU, uma única região da imagem carregada da memória compartilhada era reutilizada em muitos filtros de uma só vez, reduzindo drasticamente o tráfego de memória.

2. Camadas específicas do AlexNet e divisão entre duas GPUs

O AlexNet continha 8 camadas treináveis (5 convolucionais e 3 totalmente conectadas), totalizando cerca de 60 milhões de parâmetros. Como uma única GTX 580 não dispunha dos mais de 3 GB de VRAM necessários para ativações, pesos e gradientes, Krizhevsky dividiu a rede verticalmente em dois fluxos paralelos.

CamadaTipoTotal de filtros / neurôniosDivisão por GPUComunicação entre GPUs
EntradaImagem RGB224 × 224 × 3Copiada para ambas as GPUsNenhuma
Conv 111×11 Conv (passo 4) + MaxPool96 filtros48 filtros por GPUIsolada (sem sincronização)
Conv 25×5 Conv + MaxPool256 filtros128 filtros por GPUIsolada (lê apenas a Conv 1 da própria GPU)
Conv 33×3 Conv384 filtros192 filtros por GPUSincronização completa (lê todos os 256 mapas de ambas as GPUs)
Conv 43×3 Conv384 filtros192 filtros por GPUIsolada (lê apenas a Conv 3 da própria GPU)
Conv 53×3 Conv + MaxPool256 filtros128 filtros por GPUIsolada (lê apenas a Conv 4 da própria GPU)
FC 6Totalmente conectada + Dropout4.096 neurônios2.048 neurônios por GPUSincronização completa (conecta-se a todas as saídas da Conv 5)
FC 7Totalmente conectada + Dropout4.096 neurônios2.048 neurônios por GPUSincronização completa (conecta-se a todos os neurônios da FC 6)
FC 8Totalmente conectada (Softmax)1.000 classes1.000 classes (combinadas)Sincronização completa (produz as previsões finais do ImageNet)
  • Especialização natural das características. Curiosamente, como as camadas 1 e 2 nunca se comunicavam entre GPUs, as duas placas desenvolviam consistentemente funções especializadas. Uma GPU aprendia detectores de bordas e texturas independentes de cor (filtros em escala de cinza semelhantes aos de Gabor), enquanto a outra se especializava em manchas e tonalidades de cores específicas.
  • Minimização dos gargalos do PCIe. Transferir dados pelo barramento PCIe da placa-mãe era lento. Ao restringir rigorosamente a comunicação entre GPUs à Conv 3 e às camadas totalmente conectadas, Krizhevsky mantinha as GPUs calculando em velocidade máxima sem paradas para transferências de dados.

3. O que aconteceu depois na era ImageNet

A vitória do AlexNet iniciou uma corrida anual na competição ImageNet, levando as redes de 8 camadas a mais de 150 em apenas três anos.

  • 2013 – ZFNet (visualização e ajuste). Matthew Zeiler e Rob Fergus introduziram técnicas de deconvolução para visualizar o que o AlexNet realmente estava vendo nas camadas ocultas. Ao diminuir os filtros da primeira camada do AlexNet de 11×11 para 7×7 e reduzir o passo, o ZFNet baixou a taxa de erro top-5 no ImageNet de 15,3% para 14,8%.
  • 2014 – VGGNet (profundidade com filtros uniformes 3×3). Pesquisadores de Oxford demonstraram que empilhar muitas convoluções pequenas de 3×3 (até 16 ou 19 camadas) funcionava melhor do que usar filtros grandes isolados (como 11×11 ou 5×5). Duas camadas 3×3 empilhadas cobrem a mesma área de visão de 5×5 com menos parâmetros e ativações ReLU não lineares adicionais, reduzindo as taxas de erro para 7,3%.
  • 2014 – GoogLeNet / Inception (eficiência multiescala). O Google introduziu o módulo Inception, que executava convoluções de 1×1, 3×3 e 5×5 em paralelo dentro da mesma camada e combinava as saídas. Usando convoluções de 1×1 de baixo custo para comprimir a profundidade dos canais antes dos cálculos caros, o GoogLeNet chegou a 22 camadas e a uma taxa de erro de 6,7%, usando 12 vezes menos parâmetros que o AlexNet.
  • 2015 – ResNet (conexões de salto & 152 camadas). Simplesmente empilhar mais camadas acabava prejudicando a precisão do treinamento, porque os gradientes desapareciam durante a retropropagação. A Microsoft Research resolveu isso com conexões residuais (conexões de salto), permitindo que os dados contornassem camadas por atalhos diretos de identidade. Isso viabilizou redes de 152 camadas, alcançando uma taxa de erro top-5 de 3,57% e superando pela primeira vez o desempenho humano no benchmark (~5%).

Mais notícias: IA e Tecnologia