This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.
Um modelo de 70B em FP16 precisa de 140GB. Duas A100s apenas para os pesos. Quantize para FP8: uma GPU de 80GB. INT4: um MacBook.
Tipo: Build
Idiomas: Python (com numpy)
Pré-requisitos: Fase 10, Lições 01-10 (LLMs do Zero)
Tempo: ~120 minutos
Objetivos de Aprendizado
Implementar quantização simétrica e assimétrica de FP16 para INT8 e INT4, incluindo redimensionamento por tensor e por canal
Calcular a economia de memória da quantização e determinar qual precisão cabe na VRAM de uma determinada GPU
Explicar a diferença entre quantização pós-treinamento (PTQ) e treinamento consciente de quantização (QAT)
Aplicar GPTQ ou AWQ para quantizar um modelo real e medir a compensação entre precisão e memória em um benchmark
O Problema
O Llama 3 70B possui 70 bilhões de parâmetros. Cada parâmetro é um número de ponto flutuante de 16 bits. Isso representa 140 bilhões de bytes. 140GB. Uma única A100 possui 80GB de VRAM. Você não consegue sequer carregar os pesos, muito menos executar inferência, em uma única GPU. Você precisa de duas A100s a
/hora cada apenas para servir um modelo.
Mas 16 bits por parâmetro é um desperdício. A maioria dos pesos em uma rede neural se agrupa perto de zero. Todo o intervalo dinâmico do FP16 (de 0.000000059 a 65.504) está quase totalmente sem uso. Se você medir a distribuição real dos pesos no Llama 3 70B, 95% deles ficam entre -0.1 e +0.1. Você está queimando 16 bits para representar valores que poderiam caber em 4.
A quantização substitui números de alta precisão por outros de menor precisão. FP16 para FP8 corta a memória pela metade. FP16 para INT4 a reduz para um quarto. Aquele modelo de 140GB se torna 35GB. Ele cabe em uma única GPU de consumo. Vá para a quantização de 2 bits (agressiva, com perdas, mas utilizável para algumas tarefas) e o mesmo modelo rodará em um laptop de 16GB.
O custo é a precisão. Cada bit que você remove destrói informações. A questão é quanta precisão você perde e onde. Um modelo INT4 bem quantizado retém 95-99% da qualidade do original na maioria dos benchmarks. Uma quantização ingênua para INT4 pode destruir o modelo completamente. A diferença está na técnica.
Quantizações da comunidade do Llama 3 para INT4 com GPTQ mostram cerca de 1-2 pontos de perplexidade perdidos no WikiText. A Mistral lançou checkpoints em FP8 do Mixtral 8x22B com zero perda de qualidade mensurável no MMLU. O formato GGUF alimenta o llama.cpp, executando modelos 70B em MacBooks com chips da série M. A quantização não é um "hack". É o caminho de implantação padrão para todo modelo maior que 7B.
O Conceito
Formatos Numéricos: O que Cada Bit Faz
Todo número de ponto flutuante tem três partes: sinal, expoente e mantissa (também chamada de significando). O sinal é um bit. O expoente determina o intervalo (quão grande ou pequeno o número pode ser). A mantissa determina a precisão (quantas casas decimais você obtém).
FP32 é precisão total. 23 bits de mantissa fornecem cerca de 7 dígitos decimais de precisão. Intervalo: aproximadamente 1.2 x 10^-38 a 3.4 x 10^38. O treinamento costumava ocorrer exclusivamente em FP32. Ele ainda ocorre para acumulação (somas acumuladas durante a multiplicação de matrizes).
O FP16 divide os bits pela metade. 10 bits de mantissa fornecem cerca de 3,3 dígitos decimais. O expoente encolhe para 5 bits, reduzindo drasticamente o intervalo (valor máximo ~65.504). Isso é aceitável para os pesos (que se agrupam perto de zero), mas perigoso para ativações e gradientes que podem ter picos durante o treinamento. O treinamento em FP16 requer escalonamento de perda para evitar subfluxo (underflow).
O BF16 (Brain Float 16) mantém o expoente de 8 bits do FP32, mas encolhe a mantissa para 7 bits. Mesmo intervalo do FP32, menor precisão que o FP16. O Google o projetou especificamente para aprendizado profundo. A intuição: o intervalo importa mais do que a precisão para redes neurais. Um gradiente de 10^-20 que sofre subfluxo para zero em FP16 sobrevive em BF16. Um peso de 0.07342 que arredonda para 0.0734 em BF16 é próximo o suficiente. Todo treinamento moderno usa BF16 ou uma mistura de BF16/FP32.
O FP8 vem em dois sabores. E4M3 (4 expoentes, 3 mantissas) é usado para pesos e ativações durante a inferência. E5M2 (5 expoentes, 2 mantissas) é usado para gradientes durante o treinamento, onde o intervalo importa mais do que a precisão. A inferência em FP8 em GPUs H100 alcança uma aceleração de 30-50% sobre o FP16 com perda de qualidade insignificante.
O INT8 é um formato de número inteiro. Sem expoente, sem mantissa. Apenas 256 valores uniformemente espaçados de -128 a 127. Você precisa de um fator de escala para mapear pesos de ponto flutuante para este intervalo. A vantagem: a aritmética de inteiros é mais rápida e consome menos energia do que a de ponto flutuante. A multiplicação de matrizes INT8 em uma A100 roda a 624 TOPS contra 312 TFLOPS para FP16.
O INT4 vai além. Apenas 16 valores possíveis. O fator de escala faz o trabalho pesado. A qualidade depende inteiramente de como você escolhe a escala e de quais pesos você quantiza. Métodos INT4 de última geração (GPTQ, AWQ) mantêm mais de 95% da qualidade original do modelo.
graph LR
subgraph Formats["Panorama de Formatos Numéricos"]
direction TB
FP32["FP32\n32 bits\n4 bytes/param\nPadrão de ouro de treinamento"]
BF16["BF16\n16 bits\n2 bytes/param\nPadrão de treinamento"]
FP16["FP16\n16 bits\n2 bytes/param\nLinha de base de inferência"]
FP8["FP8\n8 bits\n1 byte/param\n30-50% mais rápido"]
INT8["INT8\n8 bits\n1 byte/param\n2x vazão (throughput)"]
INT4["INT4\n4 bits\n0.5 bytes/param\n4x compressão"]
end
FP32 -->|"treinamento"| BF16
BF16 -->|"inferência"| FP16
FP16 -->|"nativo na H100"| FP8
FP16 -->|"implantação em servidor"| INT8
FP16 -->|"borda/laptop"| INT4
style FP32 fill:#1a1a2e,stroke:#0f3460,color:#fff
style BF16 fill:#1a1a2e,stroke:#0f3460,color:#fff
style FP16 fill:#1a1a2e,stroke:#ffa500,color:#fff
style FP8 fill:#1a1a2e,stroke:#51cf66,color:#fff
style INT8 fill:#1a1a2e,stroke:#51cf66,color:#fff
style INT4 fill:#1a1a2e,stroke:#e94560,color:#fff
Como Funciona a Quantização
A operação principal é simples. Pegue um tensor de valores de ponto flutuante, encontre um fator de escala, multiplique, arredonde para o número inteiro mais próximo e armazene os inteiros mais o fator de escala.
O erro é o erro de arredondamento. Cada valor pode diferir no máximo por scale / 2. O erro total em uma camada depende de quantos pesos você tem e de quão sensível o modelo é a perturbações nesses pesos.
Quantização por tensor vs. por canal. A quantização por tensor usa um único fator de escala para toda a matriz de pesos. Simples, mas com perdas: se uma coluna tiver valores grandes e outra tiver valores pequenos, os valores pequenos perderão a maior parte de sua precisão. A quantização por canal usa um fator de escala por canal de saída (por linha ou coluna da matriz de pesos). Mais sobrecarga (você armazena N fatores de escala em vez de 1), mas com qualidade drasticamente superior. Todo método de quantização em produção usa granularidade por canal ou ainda mais fina.
A quantização assimétrica adiciona um deslocamento de ponto zero: quantized = round(tensor / scale) + zero_point. Isso lida com distribuições que não estão centralizadas em zero. As ativações ReLU, por exemplo, são sempre não negativas. A quantização simétrica desperdiça metade do intervalo de inteiros em valores negativos que nunca aparecem. A quantização assimétrica mapeia o intervalo real [min, max] para o intervalo de inteiros completo.
Hierarquia de Sensibilidade
Nem tudo em um modelo tolera a quantização igualmente. Existe uma hierarquia clara.
Pesos (mais robustos). Os pesos do modelo mudam lentamente durante o treinamento e seguem uma distribuição aproximadamente gaussiana centrada perto de zero. Eles são quantizados facilmente. Pesos INT8 com escalas por canal produzem resultados quase sem perdas. INT4 exige métodos mais sofisticados, mas funciona.
Ativações (sensibilidade moderada). As ativações são os valores intermediários que fluem pela rede durante a inferência. Elas têm um intervalo dinâmico mais amplo do que os pesos e contêm valores discrepantes (outliers). Uma única cabeça de atenção pode produzir valores de ativação 100x maiores que a média. Esses outliers são essenciais para a qualidade do modelo. Quantizá-los ingenuamente destrói informações. Soluções: manter os canais de outliers em maior precisão (LLM.int8()), usar escalas de ativação por token ou por canal.
KV cache (alta sensibilidade). O cache de chave-valor (KV cache) armazena os estados de atenção para todos os tokens anteriores. Em comprimentos de contexto longos, o KV cache domina a memória. Para um modelo 70B com contexto de 32K, o KV cache sozinho consome 40GB em FP16. Quantizar o KV cache para FP8 ou INT8 economiza uma quantidade massiva de memória, mas qualquer erro se acumula em todas as computações de atenção futuras. O impacto na qualidade aumenta com o comprimento da sequência.
Logits de atenção (mais sensíveis). O softmax na atenção é altamente sensível a pequenas mudanças em suas entradas. Um erro de quantização de 0.01 em um logit pré-softmax pode desviar a distribuição de atenção de maneira significativa. A maioria dos esquemas de quantização mantém o cálculo de atenção em maior precisão (FP16 ou BF16), mesmo quando todo o resto é quantizado.
graph TD
subgraph Sensitivity["Sensibilidade de Quantização (Baixa para Alta)"]
direction LR
W["Pesos\nGaussiano, perto de zero\nINT4 funciona bem"]
A["Ativações\nIntervalo mais amplo, outliers\nINT8 com cuidado"]
KV["KV Cache\nErros se acumulam\nFP8 ou INT8"]
ATT["Logits de Atenção\nSoftmax amplifica o erro\nManter em FP16"]
end
W -->|"seguro"| A
A -->|"cuidadoso"| KV
KV -->|"perigoso"| ATT
style W fill:#1a1a2e,stroke:#51cf66,color:#fff
style A fill:#1a1a2e,stroke:#ffa500,color:#fff
style KV fill:#1a1a2e,stroke:#e94560,color:#fff
style ATT fill:#1a1a2e,stroke:#ff0000,color:#fff
PTQ vs. QAT
A Quantização Pós-Treinamento (PTQ) quantiza um modelo já treinado. Sem retreinamento. Você pega os pesos em FP16, calcula os fatores de escala, arredonda e faz a implantação. Rápido (minutos a horas) e barato. Funciona bem para INT8 e FP8. Para INT4, o PTQ ingênuo frequentemente falha de forma grave porque os erros de arredondamento se acumulam. Métodos PTQ avançados (GPTQ, AWQ) usam dados de calibração para minimizar o erro de quantização.
O Treinamento Consciente de Quantização (QAT) insere operações de quantização simuladas (fake quantization) na passagem direta (forward pass) durante o treinamento. O modelo aprende a colocar seus pesos onde os erros de arredondamento são pequenos. Os gradientes fluem através da quantização simulada usando o estimador direto (straight-through estimator - STE): finge-se que a operação de arredondamento tem gradiente 1. O QAT produz modelos INT4 e INT2 melhores do que o PTQ, mas requer uma execução de treinamento completa. O Google usou QAT para a disponibilização eficiente do Gemini. A Meta usou QAT para alguns alvos de implantação do Llama.
Aspecto
PTQ
QAT
Custo
Minutos a horas
Execução de treinamento completa
Qualidade em INT8
Excelente (< 0,1% de perda)
Excelente
Qualidade em INT4
Boa com GPTQ/AWQ (1-3% de perda)
Melhor (< 1% de perda)
Qualidade em INT2
Ruim
Utilizável para algumas tarefas
Dados de calibração
128-1024 exemplos
Conjunto de dados de treinamento completo
Quando usar
Implantação, iteração
Qualidade máxima com largura de bits baixa
GPTQ, AWQ, GGUF
O GPTQ (GPT Quantization) é um método PTQ de passo único (one-shot). Ele quantiza pesos uma camada de cada vez, usando um pequeno conjunto de dados de calibração (128 exemplos é o típico) para medir o Hessiano (informação de segunda ordem sobre quão sensível a saída é para cada peso). Os pesos que o Hessiano indica serem importantes são quantizados com mais cuidado. O GPTQ foi o primeiro método a tornar a quantização INT4 prática para LLMs. O perfil TheBloke no Hugging Face popularizou o GPTQ ao lançar versões quantizadas de centenas de modelos.
O AWQ (Activation-Aware Weight Quantization) observa que uma pequena fração de pesos (cerca de 1%) é desproporcionalmente importante porque eles se multiplicam com grandes valores de ativação. O AWQ identifica esses pesos salientes usando dados de calibração e os escala para cima antes da quantização (depois escala as ativações correspondentes para baixo). Isso mantém os pesos importantes em uma faixa onde a quantização INT4 é precisa. O AWQ normalmente se iguala ou supera ligeiramente a qualidade do GPTQ, sendo 1.5-2x mais rápido para aplicar.
O GGUF (GPT-Generated Unified Format) é o formato de arquivo usado pelo llama.cpp e seu ecossistema. Ele suporta quantização mista: diferentes camadas recebem diferentes larguras de bits. A primeira e a última camada (incorporação/embedding e cabeça de saída/output head) são normalmente mantidas em maior precisão. As camadas do meio recebem INT4 ou INT3. Os arquivos GGUF são independentes: pesos, tokenizador e metadados estão todos em um único arquivo. O formato é projetado para inferência em CPU e Apple Silicon, onde carregar o modelo inteiro na memória e executar multiplicações de matrizes na CPU ou Metal GPU é o caminho padrão. Q4_K_M é a variante de quantização GGUF mais popular, equilibrando qualidade e tamanho.
graph TD
subgraph Methods["Métodos de Quantização"]
direction TB
GPTQ_["GPTQ\nGuiado pelo Hessiano\nOtimização por camada\nPopular no HuggingFace"]
AWQ_["AWQ\nConsciente de ativação\nRedimensionamento de pesos salientes\n1.5-2x mais rápido que GPTQ"]
GGUF_["GGUF\nPrecisão mista\nOtimizado para CPU + Metal\nEcossistema llama.cpp"]
end
subgraph Use["Melhor Para"]
GPU["Inferência em GPU\n(CUDA, ROCm)"]
EDGE["Borda / Laptop\n(CPU, Metal)"]
end
GPTQ_ --> GPU
AWQ_ --> GPU
GGUF_ --> EDGE
style GPTQ_ fill:#1a1a2e,stroke:#ffa500,color:#fff
style AWQ_ fill:#1a1a2e,stroke:#51cf66,color:#fff
style GGUF_ fill:#1a1a2e,stroke:#0f3460,color:#fff
Medição de Qualidade
Como você sabe se o seu modelo quantizado ainda é bom?
Perplexidade (Perplexity). A métrica mais comum. Quanto menor, melhor. Calcule a perplexidade em um conjunto de dados reservado (WikiText-2 é o padrão) tanto para o modelo original quanto para o quantizado. O delta indica quanta informação a quantização destruiu. Regras gerais: delta < 0.5 é excelente, 0.5-1.0 é bom, 1.0-2.0 é aceitável para a maioria das tarefas, > 2.0 significa que algo deu errado.
Benchmarks específicos de tarefas. Execute o modelo quantizado no MMLU, HumanEval, GSM8K ou em sua suíte de avaliação personalizada. Compare com o original. A quantização afeta diferentes capacidades de maneira desigual. As tarefas de matemática e codificação são mais sensíveis à perda de precisão do que as de conhecimento geral.
Comparação de saídas. Gere respostas de ambos os modelos nos mesmos prompts e compare. LLM como juiz (LLM-as-judge - Lição 10) funciona bem aqui. Calcule uma taxa de vitória: em qual fração de prompts o modelo quantizado se iguala ou supera o original?
Latência e vazão (throughput). A quantização existe para tornar os modelos mais rápidos e baratos. Meça os tokens por segundo, o tempo até o primeiro token e o uso de memória. Um modelo quantizado que é mais lento do que o original é pior do que inútil.
Modelo
Formato
Tamanho
Perplexidade (WikiText-2)
MMLU
Tokens/seg (A100)
Llama 3 70B
FP16
140GB
3.12
79.5%
38
Llama 3 70B
FP8
70GB
3.14
79.3%
55
Llama 3 70B
GPTQ INT4
35GB
4.32
77.8%
72
Llama 3 70B
AWQ INT4
35GB
4.18
78.1%
75
Llama 3 70B
GGUF Q4_K_M
40GB
4.25
77.9%
28 (CPU)
O padrão: FP8 é quase gratuito. INT4 custa 1-2 pontos de MMLU, mas dobra a vazão e reduz a memória para um quarto. A compensação vale a pena para quase toda implantação.
Números Reais
FP16 para FP8 na H100: aceleração de inferência de 30-50%, < 0,1% de perda de qualidade. Esta é a quantização óbvia. Toda implantação na H100 deveria usá-la.
FP16 para INT8 (LLM.int8()): redução de 2x na memória, < 0,5% de perda de qualidade. A abordagem de precisão mista mantém recursos atípicos (outliers) em FP16 enquanto quantiza todo o resto para INT8.
FP16 para INT4 (GPTQ/AWQ): redução de 4x na memória, 1-3% de perda de qualidade dependendo do modelo e do método. Permite modelos 70B em uma única GPU de 48GB.
FP16 para INT4 (GGUF Q4_K_M): redução de 3,5x na memória, 1-2% de perda de qualidade. Otimizado para inferência em CPU. Um modelo 70B em Q4_K_M tem cerca de 40GB e roda a 10-15 tokens/segundo em um M3 Max com 64GB.
FP16 para INT2: redução de 8x na memória, 5-15% de perda de qualidade. Apenas viável para tarefas específicas e restritas onde você pode tolerar a degradação. Fronteira de pesquisa, não está pronto para produção para uso geral.
Construa
Passo 1: Representações de Formato Numérico
Construa a representação no nível de bits de cada formato para ver exatamente o que o sinal, o expoente e a mantissa fazem.
Meça quanta informação a quantização destrói. Erro quadrático médio, relação sinal-ruído e similaridade de cosseno entre os tensores original e reconstruído.
Passo 4: Varredura de Largura de Bits (Bit-Width Sweep)
Quantize o mesmo tensor em diferentes larguras de bits (2, 3, 4, 8, 16) e meça a qualidade em cada nível. Isso mostra exatamente onde está o declínio acentuado de qualidade (quality cliff).
Simule a quantização de diferentes partes de um transformer e meça quais componentes são os mais sensíveis. Isso demonstra a hierarquia de sensibilidade: pesos < ativações < KV cache < atenção.
O GPTQ quantiza uma coluna de cada vez, usando o Hessiano para decidir como distribuir o erro de arredondamento. Esta é uma versão simplificada que captura a ideia principal: usar dados de calibração para medir a importância dos pesos e, em seguida, quantizar os pesos menos importantes de forma mais agressiva.
def simulated_gptq(weight_matrix, calibration_inputs, num_bits=4):
n_in, n_out = weight_matrix.shape
qmin = -(2 ** (num_bits - 1))
qmax = 2 ** (num_bits - 1) - 1
H = np.zeros((n_in, n_in))
for x in calibration_inputs:
x = x.reshape(-1, 1) if x.ndim == 1 else x
for row in range(x.shape[0]):
xi = x[row].reshape(-1, 1)
H += xi @ xi.T
H /= len(calibration_inputs)
H += np.eye(n_in) * 1e-4
weight_importance = np.diag(H)
quantized = np.zeros_like(weight_matrix, dtype=np.int32)
scales = np.zeros(n_out)
errors = np.zeros(n_out)
W = weight_matrix.copy()
for col in range(n_out):
w_col = W[:, col]
abs_max = np.max(np.abs(w_col))
if abs_max == 0:
scales[col] = 1.0
continue
scale = abs_max / qmax
scales[col] = scale
q_col = np.clip(np.round(w_col / scale), qmin, qmax).astype(np.int32)
quantized[:, col] = q_col
quant_error = w_col - q_col * scale
errors[col] = np.sqrt(np.mean(quant_error ** 2))
if col < n_out - 1:
importance_weights = weight_importance / (np.max(weight_importance) + 1e-10)
for next_col in range(col + 1, min(col + 4, n_out)):
compensation = quant_error * importance_weights * 0.1
W[:, next_col] += compensation
return quantized, scales, {"column_errors": errors,
"mean_error": float(np.mean(errors)),
"max_error": float(np.max(errors))}
def dequantize_gptq(quantized, scales):
result = np.zeros_like(quantized, dtype=np.float64)
for col in range(quantized.shape[1]):
result[:, col] = quantized[:, col] * scales[col]
return result
Passo 7: Simulação de AWQ
O AWQ identifica os pesos salientes (aqueles que se multiplicam com grandes ativações) e os protege por meio de redimensionamento antes da quantização.
O vLLM suporta nativamente modelos AWQ e GPTQ. Ele lida com a desquantização durante a multiplicação de matrizes e usa atenção paginada (paged attention) para o KV cache. Para FP8 na H100, adicione --dtype float8_e4m3fn.
Entregue
Esta lição produz outputs/skill-quantization.md, um framework de decisão para escolher a estratégia de quantização correta. Dado o tamanho do seu modelo, hardware de destino e requisitos de qualidade, ele informa qual formato, method, e etapas de validação usar. Inclui cálculos de orçamento de memória, recomendações de precisão por componente e receitas de implantação para vLLM, llama.cpp e TensorRT-LLM.
Exercícios
Implementar quantização em grupo. Em vez de uma escala por canal, use uma escala por grupo de 128 pesos dentro de um canal. Isso é o que o GPTQ e o AWQ realmente usam. Compare tamanhos de grupo de 32, 64, 128 e 256 na mesma matriz de pesos. Grupos menores oferecem melhor qualidade, mas maior sobrecarga de armazenamento para os fatores de escala.
Construir um quantizador de precisão mista. Quantize a primeira e a última camada de uma rede de múltiplas camadas em INT8 enquanto quantiza as camadas intermediárias em INT4. Compare a qualidade da saída de ponta a ponta em relação ao INT4 uniforme e ao INT8 uniforme. Meça a economia de memória em comparação com o modelo totalmente em INT8.
Implementar o estimador direto (STE) para treinamento consciente de quantização. Insira operações de quantização/desquantização simuladas na passagem direta de uma rede simples de duas camadas treinada em uma tarefa de regressão. Compare a perda final entre um modelo treinado normalmente (e depois submetido a PTQ para INT4) versus um modelo treinado com QAT desde o início.
Construir um quantizador consciente de outliers inspirado em LLM.int8(). Detecte canais onde a magnitude da ativação excede 6x a média. Mantenha esses canais em FP16 e quantize todo o resto para INT8. Meça a qualidade de ponta a ponta na camada do transformer do Passo 5 com limites variados de outliers (3x, 6x, 10x).
Implementar um painel (dashboard) de qualidade de quantização. Dada uma matriz de pesos, calcule e exiba: o histograma de distribuição de pesos, a distribuição de erros de quantização, fatores de escala por canal, os canais pior quantizados (maior erro de reconstrução) e a similaridade de cosseno entre as saídas originais e quantizadas em 100 entradas aleatórias. Identifique quais canais devem ser mantidos em maior precisão.
Termos-Chave
Termo
O que as pessoas dizem
O que realmente significa
FP16
"Meia precisão"
Ponto flutuante de 16 bits com 5 bits de expoente e 10 bits de mantissa, valor máximo 65.504, formato padrão de inferência
BF16
"Brain float"
Ponto flutuante de 16 bits com 8 bits de expoente (mesmo intervalo do FP32) e 7 bits de mantissa, projetado pelo Google para treinamento
FP8
"Ponto flutuante de oito bits"
Duas variantes: E4M3 (inferência, mais precisão) e E5M2 (treinamento, maior intervalo), nativo na H100
INT8
"Inteiro de oito bits"
256 valores uniformemente espaçados de -128 a 127, precisa de um fator de escala para mapear a partir de pontos flutuantes
INT4
"Inteiro de quatro bits"
16 níveis no total, requer métodos sofisticados (GPTQ, AWQ) para manter a qualidade
Quantização por canal
"Uma escala por linha"
Usa um fator de escala separado para cada canal de saída em vez de um para todo o tensor, reduz dramaticamente o erro
GPTQ
"O método Hessiano"
Quantização pós-treinamento usando informações de segunda ordem para minimizar o erro de saída, uma camada por vez
AWQ
"Consciente de ativação"
Escala pesos salientes (aqueles multiplicados por grandes ativações) antes da quantização para protegê-los
GGUF
"O formato llama.cpp"
Arquivo de modelo independente com camadas de precisão mista, otimizado para inferência em CPU e Apple Silicon
PTQ
"Quantizar após o treinamento"
Converter os pesos de um modelo treinado para menor precisão sem retreinamento, rápido mas limitado sob compressão extrema
QAT
"Quantizar durante o treinamento"
Inserir quantização simulada na passagem direta para que o modelo aprenda a tolerar o arredondamento, melhor em INT4/INT2
Dados de calibração
"Os 128 exemplos"
Um pequeno conjunto de dados executado no modelo para computar estatísticas de ativação para definir os fatores de escala
Fator de escala
"O multiplicador"
Converte entre a faixa de ponto flutuante e a faixa de inteiros: float_val = int_val * scale
Delta de perplexidade
"Quanto pior"
Diferença de perplexidade entre o modelo original e o quantizado, < 0,5 é excelente, > 2,0 é um problema