1 pontos por GN⁺ 2025-03-16 | 1 comentários | Compartilhar no WhatsApp
  • Mostra que substituir Layer Norm/RMSNorm, usados quase como obrigatórios em Transformers, por Dynamic Tanh (DyT) pode alcançar desempenho semelhante ou melhor do que modelos tradicionais com normalização
  • DyT é uma operação elemento a elemento na forma DyT(x) = tanh(αx), surgida da observação de que a Layer Normalization dentro de Transformers frequentemente cria um mapeamento de entrada e saída em forma de S, parecido com tanh
  • A implementação cabe em poucas linhas de PyTorch e aplica escala e viés à saída de tanh(alpha * x) com alpha, weight e bias treináveis
  • A avaliação cobre amplamente modelagem de visão, linguagem, fala e sequências de DNA, incluindo ViT, ConvNeXt, MAE, DINO, DiT, LLaMA, wav2vec 2.0, HyenaDNA e Caduceus
  • Mesmo sem ajuste adicional de hiperparâmetros, os resultados em várias configurações foram semelhantes ou melhores que os de modelos equivalentes baseados em normalização, levando a repensar a premissa de que camadas de normalização são indispensáveis

Onde o Dynamic Tanh muda o jogo

  • DyT é uma camada simples que substitui Layer Norm ou RMSNorm em blocos Transformer
  • A operação central é DyT(x) = tanh(αx), aplicada elemento a elemento
  • Mostra que Transformers sem camadas de normalização podem ter desempenho semelhante ou até superior ao de Transformers tradicionais com normalização
  • A ideia parte da observação de que a Layer Normalization em Transformers frequentemente produz uma relação entrada-saída parecida com uma função tanh escalada

Como é implementado

  • O módulo DyT pode ser implementado de forma curta em PyTorch
class DyT(nn.Module):
    def __init__(self, num_features, alpha_init_value=0.5):
        super().__init__()
        self.alpha = nn.Parameter(torch.ones(1) * alpha_init_value)
        self.weight = nn.Parameter(torch.ones(num_features))
        self.bias = nn.Parameter(torch.zeros(num_features))

    def forward(self, x):
        x = torch.tanh(self.alpha * x)
        return x * self.weight + self.bias
  • alpha é um parâmetro treinável, com valor inicial definido como 0.5
  • weight e bias também são parâmetros treináveis, aplicados à saída de tanh(alpha * x)

Observação vinda da Layer Normalization

  • A Layer Normalization (LN) em Transformers gera um mapeamento de entrada e saída próximo de uma função tanh escalada
  • Nas camadas iniciais, esse mapeamento tende a ser mais próximo de linear
  • À medida que as camadas se aprofundam, a curva em S característica da função tanh aparece com mais clareza
  • Os alvos da observação incluem camadas LN selecionadas de Vision Transformer (ViT), do modelo de fala wav2vec 2.0 e de Diffusion Transformer (DiT)

Escopo da avaliação e resultados

  • O DyT foi avaliado em várias arquiteturas e tarefas
    • Visão com aprendizado supervisionado: ViT, ConvNeXt
    • Visão com aprendizado autossupervisionado: MAE, DINO
    • Modelos de difusão: DiT
    • Grandes modelos de linguagem: LLaMA
    • Fala com aprendizado autossupervisionado: wav2vec 2.0
    • Modelagem de sequências de DNA: HyenaDNA, Caduceus
  • Em todos os casos, Transformers com DyT mostraram desempenho semelhante ou melhor que seus equivalentes baseados em normalização
  • O escopo da avaliação é amplo, cobrindo de reconhecimento a geração, de aprendizado supervisionado a autossupervisionado, e de visão computacional a modelos de linguagem

Materiais de referência

  • Download Paper: artigo com todos os detalhes da pesquisa
  • View on GitHub: repositório para verificar detalhes da implementação
  • View Summary: resumo breve dos resultados da pesquisa
  • Transformers without Normalization foi aceito como artigo da CVPR 2025

1 comentários

 
GN⁺ 2025-03-16
Comentários do Hacker News
  • Se isso for verdade, é uma melhoria incremental bem interessante. Não parece aumentar o desempenho do modelo de forma significativa, mas tem custo computacional menor que o RMSNorm usado pela maioria dos LLMs de ponta hoje, então o treinamento pode ficar mais rápido e barato
    • Ainda assim, o RMSNorm representa uma parte relativamente pequena do custo total de computação de um Transformer. Em geral, operações de redução podem ser fundidas com as operações anteriores e posteriores
    • Acabei de aplicar isso ao meu benchmark pessoal de treinamento de Transformer, e o resultado foi bem decepcionante. A convergência foi muito mais lenta do que com RMSNorm
      Ajustar o alpha quase não ajudou, então talvez seja necessário um tuning considerável de hiperparâmetros ou uma inicialização mais sofisticada. Tentei tanto a inicialização padrão do PyTorch quanto a inicialização ortogonal, mas não houve diferença
      Ou talvez o otimizador escalar que eu uso não combine bem com isso. Uso um otimizador escalar customizado que converge mais rápido que o Adam, mas na camada DyT ele pareceu ficar só no nível do Adam
      Também pode ser o tipo de coisa que só alcança os outros depois de dezenas de bilhões de tokens, mas não tenho orçamento para testar por tanto tempo
  • Com formatos de baixa precisão como float8, normalmente é preciso promover as ativações para BF16 antes da normalização. Então, quanto menor a precisão, maior passa a ser a parcela de computação ocupada pelas camadas de normalização
    Se for possível substituir essas camadas, isso ajudaria bastante a reduzir o custo computacional
  • Preciso ler os detalhes, mas remover a normalização pode ser algo importante. Quando se tenta uma arquitetura nova, sempre é trabalhoso ajustar tudo para que a rede fique devidamente normalizada
    O tanh também deve ter outros efeitos. Às vezes a normalização está resolvendo problemas de condicionamento. Ainda assim, é bom ter mais alternativas
  • Então desaparecimento do gradiente não é mais um problema?
    • Se você inicializar as camadas corretamente, dá para manter a magnitude do gradiente sem desaparecer nem explodir mesmo em redes profundas. Por exemplo, se você ajustar a média da saída de cada camada para 0 e o desvio padrão para 1, os gradientes também ficam em uma faixa razoável
      Recomendo o artigo original do ResNet, de Kaiming He e outros, além dos trabalhos posteriores
      Para uma abordagem moderna sobre RNNs, vale ler o paper da DeepMind: https://arxiv.org/abs/2303.06349
      A ideia central é que o maior autovalor, isto é, o raio espectral, deve ficar perto de 1. Isso significa que, ao aplicar repetidamente a transformação linear, as ativações não crescem nem diminuem
    • Eu diria que o ResNet praticamente resolveu o desaparecimento do gradiente. Já a explosão do gradiente costuma ser tratada com boa inicialização de parâmetros e normalização. Este paper está basicamente propondo uma alternativa à normalização
    • Boa pergunta. Isso era um problema da época em que se usava tanh como função de ativação, antes das conexões residuais e das camadas de normalização. Usar tanh como normalização, com outras funções de ativação e conexões residuais presentes, parece aceitável
    • Como mostrado na figura, o Transformer aprende o residual. É da forma y = x + f(x)
  • Posso estar vendo errado, mas o gráfico do paper, ao comparar LNinput e LNoutput, parece colocar peso e viés também depois de tanh(a*x)
    Para ver a similaridade, não seria melhor comparar com o resultado da LayerNorm sem peso e viés?
    Se o resultado final for bom, tudo bem, mas olhando separadamente só para a parte que está sendo substituída, talvez desse para entender melhor o que está acontecendo
    • Pela implementação, parece que eles aplicam peso e viés depois de calcular o tanh
  • Em termos práticos, o que isso significa?
    • Segundo o resumo, ao inserir DyT, um Transformer sem normalização pode igualar ou superar o desempenho da versão com normalização na maioria dos casos, sem necessidade de tuning de hiperparâmetros