25 pontos por xguru 2024-07-31 | Ainda não há comentários. | Compartilhar no WhatsApp
  • Modelos de linguagem de grande porte (LLMs) são grandes demais para rodar em hardware comum e, como normalmente têm bilhões de parâmetros, exigem GPUs com grande quantidade de VRAM
  • Por isso, cada vez mais pesquisas têm se concentrado em tornar esses modelos menores por meio de treinamento aprimorado, adaptadores etc., e uma das principais técnicas dessa área é a quantização (Quantization)

Part 1: o "problema" dos modelos de linguagem de grande porte

  • LLM (Large Language Model) recebeu esse nome de acordo com a quantidade de parâmetros que contém
  • Esses modelos geralmente incluem bilhões de parâmetros (em sua maioria pesos), o que pode gerar um custo de armazenamento bastante alto
  • Durante a inferência, as ativações são geradas pelo produto entre entradas e pesos, e também podem ser consideravelmente grandes
  • Portanto, tenta-se representar bilhões de valores da forma mais eficiente possível, minimizando ao mesmo tempo o espaço necessário para armazenar um determinado valor

Como representar valores numéricos

  • Um dado valor muitas vezes é representado como um número de ponto flutuante (real)
  • Esses valores são representados em "bits", e o padrão IEEE-754 descreve como os bits indicam uma das funções de sinal, expoente e mantissa (fraction) para representar um valor
  • Em geral, quanto mais bits são usados para representar um valor, maior é a precisão
  • Quanto mais bits disponíveis, maior também é a faixa de valores que pode ser representada

Restrições de memória

  • Supondo um modelo com 70 bilhões de parâmetros, se for usado FP32 (full-precision), seriam necessários 280 GB de memória apenas para carregar o modelo
  • Por isso, é muito importante minimizar o número de bits usados para representar os parâmetros do modelo, mas quando a precisão diminui, a acurácia do modelo também costuma cair
  • O objetivo é reduzir o número de bits usados para representar valores mantendo a acurácia, e é exatamente aí que entra a quantização (quantization)

Part 2: introdução à quantização

  • A quantização busca reduzir a precisão dos parâmetros do modelo de uma largura de bits alta (por exemplo, ponto flutuante de 32 bits) para uma largura de bits menor (por exemplo, inteiro de 8 bits)
  • Cada vez que o número de bits é reduzido, é feito um mapeamento para "comprimir" os parâmetros originais em uma representação de poucos bits

Tipos de dados comuns

FP16

  • Ao passar de FP32 para FP16 (half precision), a faixa de valores que o FP16 pode assumir se torna significativamente menor que a do FP32

BF16

  • Para obter uma faixa de valores semelhante à do FP32, foi introduzido o bfloat16, uma espécie de "FP32 truncado"
  • BF16 usa a mesma quantidade de bits que FP16, mas pode ter uma faixa de valores mais ampla e é frequentemente usado em aplicações de deep learning

INT8

  • Ao reduzir ainda mais o número de bits, a representação deixa de se parecer com ponto flutuante e se aproxima de uma representação baseada em inteiros

Quantização simétrica

  • A faixa de valores originais em ponto flutuante é mapeada para uma faixa simétrica em torno de 0 no espaço quantizado
  • O valor quantizado de 0 no espaço de ponto flutuante é exatamente 0 no espaço quantizado

Quantização assimétrica

  • Diferentemente da quantização simétrica, ela não é simétrica em torno de 0
  • Mapeia o valor mínimo (β) e o valor máximo (α) da faixa em ponto flutuante para o mínimo e o máximo da faixa quantizada
  • Um dos métodos é chamado de quantização com zero-point

Mapeamento de faixa e clipping

  • Se toda a faixa de um vetor for mapeada, outliers podem fazer com que todos os valores pequenos sejam mapeados para a mesma representação de poucos bits, perdendo capacidade de diferenciação
  • Em vez disso, pode-se optar por fazer clipping de determinados valores
  • Clipping consiste em definir uma faixa dinâmica diferente para os valores originais, fazendo com que todos os outliers tenham o mesmo valor
  • O erro de quantização dos valores que não são outliers diminui bastante, mas o erro de quantização dos outliers aumenta

Calibração (Calibration)

Pesos (e bias)

  • Pesos e bias podem ser considerados valores estáticos conhecidos antes da execução do modelo
  • Como há muito menos bias do que pesos, eles são mantidos em precisão mais alta (por exemplo, INT16), e o principal esforço de quantização se concentra nos pesos
  • Técnicas de calibração para pesos estáticos e conhecidos incluem selecionar manualmente percentis da faixa de entrada, otimizar o erro quadrático médio (MSE) entre os pesos originais e quantizados, ou minimizar a entropia (divergência KL) entre os valores originais e os quantizados

Ativações

  • As entradas são continuamente atualizadas ao longo do LLM e geralmente são chamadas de "ativações"
  • Esses valores mudam sempre que cada dado de entrada é alimentado no modelo durante a inferência, o que torna difícil quantizá-los com precisão
  • Como esses valores são atualizados após cada camada oculta, só é possível saber no que eles vão se transformar durante a inferência quando os dados de entrada passam pelo modelo

Part 3: quantização pós-treinamento (PTQ - Post-Training Quantization)

Quantização dinâmica

  • As ativações são coletadas depois que os dados passam por uma camada oculta
  • Essa distribuição de ativações é usada para calcular os valores de zero-point (z) e fator de escala (s) necessários para quantizar a saída
  • O processo se repete cada vez que os dados passam por uma nova camada. Portanto, cada camada tem seus próprios valores de z e s e um esquema de quantização diferente

Quantização estática

  • Os valores de zero-point (z) e fator de escala (s) são calculados antecipadamente, e não durante a inferência
  • Para encontrar esses valores, um conjunto de dados de calibração é fornecido ao modelo para coletar essas distribuições potenciais
  • Ao realizar a inferência real, os valores de s e z não são recalculados; eles são usados globalmente para quantizar todas as ativações
  • Em geral, a quantização dinâmica tende a ser um pouco mais precisa, porque tenta calcular os valores de s e z para cada camada oculta, mas isso pode aumentar o tempo de computação
  • Já a quantização estática é menos precisa, mas mais rápida porque os valores de s e z já são conhecidos

O território da quantização de 4 bits

  • Ir para menos de 8 bits tem se mostrado uma tarefa difícil, porque o erro de quantização aumenta a cada bit perdido
  • Exploração de dois métodos comumente compartilhados no HuggingFace: GPTQ e GGUF

GPTQ

  • Um dos métodos mais conhecidos atualmente para quantizar em 4 bits
  • Usa quantização assimétrica e é aplicado camada por camada, de modo que cada camada é processada de forma independente antes de passar para a próxima
  • Durante o processo de quantização por camada, os pesos da camada são primeiro transformados pelo Hessian inverso, que é a segunda derivada da função de perda do modelo e indica o quanto a saída do modelo é sensível a mudanças em cada peso
  • Em termos simples, isso mostra a (importância) inversa de cada peso na camada
  • Pesos com valores pequenos na matriz Hessiana são mais importantes, porque pequenas mudanças nesses pesos podem causar grandes alterações no desempenho do modelo

GGUF

  • GPTQ é um bom método de quantização para executar um LLM inteiro na GPU, mas nem sempre se dispõe dessa capacidade
  • Em vez disso, é possível usar GGUF para fazer offload de todas as camadas do LLM para a CPU
  • Isso permite usar CPU e GPU ao mesmo tempo quando não há VRAM suficiente

Part 4: treinamento com consciência de quantização (QAT - Quantization Aware Training)

  • Na parte 3, vimos como quantizar um modelo após o treinamento, mas essa quantização tem a desvantagem de não considerar o processo real de treinamento
  • É exatamente aí que entra o treinamento com consciência de quantização (QAT). Diferentemente do PTQ, o QAT busca aprender o procedimento de quantização durante o treinamento
  • O QAT tende a ser mais preciso do que o PTQ, porque a quantização já foi considerada durante o treinamento

A era dos LLMs de 1 bit: BitNet

  • BitNet representa os pesos do modelo com um único bit: -1 ou 1
  • Isso é feito injetando diretamente o processo de quantização na arquitetura Transformer
  • A arquitetura Transformer é usada como base da maioria dos LLMs e consiste em cálculos que incluem camadas lineares
  • O BitNet substitui essas camadas lineares por algo chamado BitLlinear

Quantização de pesos

  • Durante o treinamento, os pesos são armazenados em INT8 e depois quantizados para 1 bit usando a estratégia básica da função sinal
  • Essencialmente, a distribuição dos pesos é deslocada para ficar centrada em 0, e então tudo à esquerda de 0 recebe -1, enquanto tudo à direita recebe 1

Quantização de ativações

  • Para quantizar as ativações, o BitLinear usa quantização absmax para converter ativações de FP16 para INT8, porque a multiplicação de matrizes (×) exige maior precisão

Desquantização

  • Foram rastreados α (o maior valor absoluto das ativações) e β (o valor absoluto médio dos pesos), e esses valores depois ajudam a desquantizar as ativações de volta para FP16
  • As ativações de saída são reescaladas com {α, γ} e desquantizadas de volta para a precisão original

Todos os modelos de linguagem de grande porte têm 1,58 bit

  • O BitNet 1.58b foi introduzido para melhorar o problema de escalabilidade mencionado anteriormente
  • Nesse novo método, cada peso individual do modelo não pode assumir apenas -1 ou 1, mas agora também 0, tornando-se ternário
    • Curiosamente, apenas adicionar 0 já melhora bastante o BitNet e torna o cálculo muito mais rápido

O poder do 0

  • Por que adicionar 0 representa uma melhora tão grande? Isso está totalmente relacionado à multiplicação de matrizes
  • Quando se têm pesos quantizados em 1,58 bit, não só a velocidade de cálculo aumenta muito, já que basta realizar multiplicações, como também se torna possível fazer filtragem de características

Quantização

  • Para realizar a quantização dos pesos, o BitNet 1.58b usa a quantização absmean, uma variação da quantização absmax que vimos antes
  • Ela simplesmente comprime a distribuição dos pesos e usa a média absoluta (α) para quantizar os valores, que são então arredondados para -1, 0 ou 1
  • Em comparação com o BitNet, a quantização de ativações é igual com uma exceção. Em vez de ajustar as ativações para a faixa [0, 2ᵇ⁻¹], agora se usa quantização absmax para ajustá-las para [-2ᵇ⁻¹, 2ᵇ⁻¹]
  • A quantização de 1,58 bit exigiu (principalmente) dois truques:
    • adicionar 0 para criar uma representação ternária [-1, 0, 1]
    • quantização absmean para os pesos
  • "O BitNet b1.58 de 13B é mais eficiente do que um LLM FP16 de 3B em termos de latência, uso de memória e consumo de energia"

  • Portanto, é possível obter um modelo leve porque se usa apenas a quantização computacionalmente eficiente de 1,58 bit

Ainda não há comentários.

Ainda não há comentários.