Guia de quantização de modelos: dos fundamentos ao serving em produção
Tradução automática Este artigo foi traduzido automaticamente a partir da versão original em inglês.
A quantização utiliza menos bits para representar os valores de um modelo. Um percurso de serving pode quantizar pesos, ativações, o KV cache ou uma combinação destes, e cada alvo resolve um problema de serving diferente.
Escolha o alvo com base no bottleneck atual: memória dos pesos, computação das ativações, tamanho do KV cache, kernels, hardware, dados de calibração ou qualidade. Um modelo de 4 bits pode caber na VRAM e, ainda assim, ser lento quando utiliza um kernel não otimizado, como demonstra o benchmark do vLLM da JarvisLabs. O FP8 funciona bem em hardware NVIDIA Hopper com um runtime compatível, mas não oferece qualquer benefício nativo em GPUs não suportadas. A matriz de hardware do TensorRT-LLM apresenta os percursos suportados. Para contextos longos ou elevada concorrência, a quantização do KV cache pode poupar mais memória do que a quantização dos pesos.
Engenheiros de ML e de plataformas podem utilizar o bottleneck para selecionar um formato e um runtime candidatos, validando depois esse percurso de serving específico antes do deployment.
Para consultar o artefacto curto e a comparação entre métodos, veja LLM Quantization Formats.
1. Comece pelo bottleneck
Identifique o que limita a workload antes de escolher a largura de bits. A resposta pode ser a memória dos pesos do modelo, a computação de prefill, a largura de banda do decode ou o KV cache, e não a precisão numérica por si só.
Bottlenecks comuns e respetivos pontos de partida:
| Se este for o problema | Comece aqui | Ferramentas típicas | Verifique antes do deployment |
|---|---|---|---|
| Os pesos do modelo não cabem na VRAM | Quantização weight-only W4A16 | AWQ ou GPTQ com llm-compressor ou GPTQModel | Perplexidade, programação, reasoning, seguimento de instruções |
| O serving de elevado throughput está limitado pela computação | FP8 ou INT8 W8A8 | FP8 PTQ, SmoothQuant, TensorRT-LLM, vLLM | Throughput, TTFT, precisão nas tarefas |
| O contexto longo ou a elevada concorrência esgotam a GPU | Quantização do KV cache | vLLM, TensorRT-LLM ou Transformers QuantizedCache | Recuperação em contexto longo, latência, segurança e qualidade |
| Inferência local em CPU, Apple Silicon ou desktop | Ficheiros GGUF com encodings de tensores locais | llama.cpp, Ollama, LM Studio | Latência do prompt, utilização de RAM, encoding de tensor selecionado e qualidade subjetiva da saída |
| O fine-tuning de adapters tem de caber numa GPU | NF4 / QLoRA | bitsandbytes, peft | Loss de fine-tuning e qualidade do modelo merged |
| O pipeline de geração de imagens é demasiado grande ou lento | INT4 ou FP8 específico para difusão | SVDQuant, Nunchaku, torchao, NVIDIA ModelOpt | Artefactos visuais, alinhamento com o prompt, latência, VRAM |
Utilize esta tabela como mapa. As secções seguintes explicam por que motivo estes pontos de partida diferem.
Notação utilizada nas receitas de serving
- W{x}A{y} indica a precisão utilizada na matemática dos pesos e das ativações suportadas, normalmente em percursos GEMM nos engines de serving. W4A16 armazena os pesos em formato de 4 bits e mantém as ativações com precisão de 16 bits. W8A8 utiliza pesos e ativações de 8 bits nos percursos de computação suportados, mas não define automaticamente o dtype de armazenamento persistente de todos os tensores do runtime.
- FP8, INT8, INT4, NF4 são formatos numéricos. Determinam que valores podem ser representados.
- GPTQ, AWQ, SmoothQuant, QuaRot são algoritmos. Determinam como mapear um modelo treinado para um formato de menor precisão.
- GGUF é um formato de ficheiro que armazena tensores e metadados para runtimes ao estilo de GGML e
llama.cpp. Um ficheiro GGUF pode conter tipos de tensor não quantizados, comoF16,BF16ouF32, bem como encodings quantizados. Os presets incluemQ4_K_M,Q5_K_M,Q8_0,IQ*,TQ*eMXFP4. O encoding do tensor determina a escolha de quantização.GGUF, por si só, não descreve uma receita de serving CUDA-style FP8 W8A8. - KV cache é a cache de attention utilizada durante a geração. Armazena as keys e values anteriores para que o modelo não tenha de recalcular toda a conversa a cada token.
- Quantização do KV cache armazena os tensores de ativação key/value em formatos de cache de menor precisão, como FP8, INT8, INT4 ou INT2, consoante o suporte do runtime. Isto é diferente de prefix caching, PagedAttention ou offload, que determinam, respetivamente, se as entradas da cache são reutilizadas, como são alocadas ou onde residem.
- GEMM significa multiplicação geral de matrizes. A maior parte do tempo de inferência de um transformer é gasto em multiplicações de matrizes.
2. A quantização é arredondamento controlado
A quantização mapeia valores de alta precisão para um conjunto menor de valores representáveis. Esta é a definição central utilizada tanto pelo Hugging Face Optimum como pelo TensorRT-LLM. Poupa memória e largura de banda, mas introduz erro de arredondamento.
O INT4 disponibiliza apenas 16 valores discretos, pelo que mapear pesos BF16 para essa grelha cria erro de arredondamento. Métodos como GPTQ, AWQ e SVDQuant procuram preservar outliers e reduzir o erro de reconstrução. Um bom mapeamento poupa memória com pouca perda de qualidade. Um mapeamento inadequado prejudica o reasoning, o seguimento de instruções ou a fidelidade visual.
Mapeamento simétrico e assimétrico
Seguindo o mapeamento afim utilizado em guias de quantização comuns, a quantização mapeia um valor float contínuo para uma grelha discreta.
- é o valor original de alta precisão.
- é o valor quantizado.
- é a escala, ou tamanho do passo.
- é o zero point, a posição inteira que representa
0.0. - é o intervalo inteiro de destino. Os valores signed de 4 bits utilizam frequentemente .
A quantização simétrica centra a grelha em torno de zero e define :
Isto é adequado para hardware porque a matemática do runtime não precisa de subtrair um offset de zero point. A stack de quantização do PyTorch expõe estas escolhas de escala afim e zero point como parâmetros primitivos de quantização em torchao.
A quantização assimétrica desloca a grelha para cobrir intervalos enviesados:
Esta grelha deslocada pode preservar melhor ativações exclusivamente positivas, mas o offset acrescenta trabalho, a menos que o kernel o trate de forma eficiente.
A granularidade da escala é importante
O fator de escala pode abranger um tensor de pesos inteiro, um canal ou um pequeno grupo de valores. A documentação do vLLM sobre KV cache FP8 utiliza a mesma distinção entre estratégias de escala por tensor e por attention head. Grupos menores normalmente preservam melhor a qualidade, mas exigem mais metadados de escala.
| Granularidade da escala | O que partilha uma escala | Efeito na qualidade e na execução |
|---|---|---|
| Por tensor | Toda a matriz de pesos | Armazena poucos metadados, mas um outlier pode expandir a grelha e reduzir a precisão em toda a layer. |
| Por canal | Uma linha de saída | Impede que canais com intervalos estreitos partilhem o intervalo mais amplo de outro canal. Muitos percursos de pesos de 8 bits utilizam esta granularidade. |
| Por grupo | Um bloco dentro de uma linha, normalmente 64 ou 128 valores | Confina um outlier a um bloco pequeno, ao custo de mais escalas. O AutoGPTQ utiliza group_size=128 nos seus exemplos de GPTQ. |
Os pesos são estáticos, pelo que as suas escalas podem ser calculadas offline antes de carregar o modelo. As ativações mudam a cada token, o que torna os seus intervalos dependentes da workload.
| Escala das ativações | Quando o runtime escolhe a escala | Vantagem | Modo de falha ou custo |
|---|---|---|---|
| Estática | Offline, a partir de um dataset de calibração | Evita calcular a escala durante a inferência. | Prompts fora do comprimento ou da distribuição calibrados podem truncar picos de ativação e prejudicar a saída. |
| Dinâmica | Durante cada forward pass | Adapta-se aos valores atuais das ativações e à combinação de prompts. | Calcular os intervalos em cada layer acrescenta trabalho e requer kernels otimizados. |
O KV cache situa-se entre estes dois casos. As keys e values começam por ser tensores de ativação do runtime: cada layer calcula-os a partir dos hidden states durante o forward pass. Depois de gerados, deixam de ser intermediários transitórios de matmul e passam a ser estado persistente de serving, que a attention consulta para os tokens seguintes.
Um engine de serving pode armazenar esse estado com menor precisão e manter os metadados de escala junto dele. O Quantized KV Cache do vLLM, o FP8 KV Cache do TensorRT-LLM e o Transformers QuantizedCache expõem todos esta escolha de armazenamento.
A precisão de armazenamento da cache permanece separada da precisão das ativações utilizada nos kernels lineares. “Quantização do KV cache” designa uma otimização específica da cache, não todas as técnicas que reutilizam, alocam ou movem entradas da cache.
PTQ e QAT ocorrem em fases diferentes
A quantização pós-treino, ou PTQ, comprime um modelo treinado posteriormente. O quantization-aware training, ou QAT, expõe o modelo ao ruído de quantização durante o treino para que este se possa adaptar.
| Método | Quando os intervalos são aprendidos | Utilize-o quando | Custo |
|---|---|---|---|
| Weight-only PTQ | Offline, para pesos estáticos | O modelo não cabe ou o decode está limitado pela largura de banda | As ativações continuam a executar em 16 bits |
| PTQ estática | Offline, a partir de prompts de calibração | Pretende serving W8A8 rápido | Os dados de calibração têm de corresponder à produção |
| PTQ dinâmica | No runtime, por batch ou percurso de ativação | As distribuições de entrada variam muito | Trabalho adicional no runtime e suporte de hardware mais limitado |
| QAT | Durante o treino | A PTQ quebra a qualidade num modelo sensível | Infraestrutura completa de treino e muito mais computação |
Os dados de calibração têm de ser semelhantes ao tráfego que irá servir. O percurso de calibração do KV cache do vLLM, por exemplo, utiliza um dataset selecionado através de llm-compressor. Se os prompts de produção forem traces RAG longos, parágrafos curtos da Wikipédia darão números de benchmark impecáveis e um deployment avariado. A calibração escolhe escalas e intervalos estáticos de ativações ou da cache a partir dessa distribuição de texto curto; não ajusta os parâmetros fixos do modelo. Prompts reais de contexto longo podem produzir padrões de ativação diferentes. As avaliações de quantização em contexto longo medem diretamente este risco.
3. Os formatos numéricos determinam os requisitos de hardware
O formato numérico define os valores que o modelo pode representar em memória. Uma computação eficiente requer kernels do runtime e suporte de hardware para a mesma largura de bits e formato. O TensorRT-LLM documenta tanto a lista de receitas como a matriz de suporte de hardware.
| Formato | Armazenamento por valor | Bom default para | Principal aspeto a verificar |
|---|---|---|---|
| BF16 / FP16 | 2 bytes | Inferência de referência e serving compatível com treino | Elevada utilização de VRAM e tráfego elevado de largura de banda de memória |
| FP8 | 1 byte | Serving W8A8 de elevado throughput em Ada, Hopper, Blackwell | Requer tensor cores FP8 nativos e suporte do runtime |
| INT8 | 1 byte | Serving W8A8 em hardware mais antigo ou não NVIDIA | Outliers das ativações e sensibilidade à calibração estática |
| INT4 | 0,5 bytes | W4A16 quando a memória dos pesos é a principal limitação | Perda de qualidade em modelos mais pequenos ou intensivos em reasoning |
| FP4 / NVFP4 | ~0,5 bytes | Experiências da era Blackwell e primeiros percursos de serving | Requisitos específicos do compilador e runtime do hardware |
| Encodings / presets GGUF do llama.cpp | Variável | Inferência local em CPU, Apple Silicon, desktop e edge | GGUF é o contentor. O encoding do tensor é a escolha de quantização. |
| NF4 | 0,5 bytes | Treino de adapters com QLoRA | Normalmente é o formato de exportação errado para serving em produção |
BF16 e FP16 utilizam ambos 16 bits, mas distribuem a precisão de forma diferente e, por isso, falham de forma diferente. O BF16 mantém o intervalo de expoentes de 8 bits do FP32 e é mais difícil de fazer transbordar. O FP16 tem mais bits de mantissa e um intervalo de expoentes mais estreito, pelo que os picos de ativação exigem mais atenção. A avaliação de Kurtic et al. utiliza explicitamente o BF16 como baseline ao comparar formatos de serving FP8, INT8 e INT4.
O FP8 tem duas variantes comuns. O E4M3 oferece mais precisão e é normalmente utilizado para pesos e ativações no forward. O E5M2 oferece um intervalo dinâmico maior e é mais útil para gradients ou percursos de ativação voláteis. O vLLM expõe ambos os dtypes de KV cache FP8 E4M3 e E5M2. No estudo ACL 2025 de Kurtic et al., “Give Me BF16 or Give Me Death”, o FP8 W8A8 foi efetivamente lossless na família Llama-3.1 em mais de 500 000 avaliações. O resultado abrange essa família de modelos, suite de avaliação e configuração de serving. Cada deployment continua a precisar do seu próprio quality gate.
A Blackwell acrescenta formatos de microscaling, como MXFP8 e NVFP4. Em vez de uma escala para um tensor ou linha inteiros, o microscaling utiliza blocos muito pequenos. O explicador da NVIDIA sobre NVFP4 descreve valores de floating-point de 4 bits em blocos de 16, com fatores de escala FP8 e uma escala FP32 de nível superior. Esta abordagem procura oferecer uma footprint próxima de INT4 com comportamento de floating point. No entanto, requer uma arquitetura de hardware, um compilador e suporte de runtime compatíveis, razão pela qual o TensorRT-LLM lista o suporte de FP4 e FP8 por geração de GPU.
4. Quantização weight-only vs. weight-activation
A notação WxAy descreve a precisão dos pesos e das ativações, que exercem pressões diferentes sobre a GPU durante a inferência.
Durante o prefill, o modelo processa o prompt de entrada. Esta fase é normalmente limitada pela computação, porque a GPU executa grandes multiplicações de matrizes; por isso, as receitas W8A8 FP8/INT8 são importantes para serving orientado ao throughput.
Durante o decode, o modelo gera um token de cada vez. Esta fase é frequentemente limitada pela largura de banda da memória, porque a GPU continua a carregar pesos da VRAM para produzir o token seguinte. Artigos sobre weight-only, como GPTQ e AWQ, visam essa pressão reduzindo os bytes dos pesos.
W4A16 comprime os pesos e mantém as ativações em BF16 ou FP16. A GPU carrega menos bytes de pesos e depois faz dequantize dos pesos para um formato de maior precisão antes da multiplicação. Isto ajuda no decode e nos problemas de capacidade de memória. O prefill limitado pela computação pode beneficiar pouco, porque a matemática matricial continua a executar em 16 bits.
W8A8 comprime os pesos e os tensores de ativação utilizados pelos kernels de matmul suportados. Se o hardware tiver tensor cores nativos de baixa precisão, o engine de serving pode executar a matemática matricial diretamente em FP8 ou INT8. O FP8 pode, assim, ajudar o serving de elevado throughput ao reduzir o tráfego de memória e utilizar aritmética mais rápida. O KV cache tem a sua própria configuração de armazenamento; verifique separadamente o cache dtype ou a cache implementation do runtime.
Se o modelo couber por pouco na VRAM, comece pela quantização weight-only para reduzir a footprint de memória. Se o modelo couber, mas tiver dificuldades de throughput com batches elevados, avalie FP8 ou INT8 W8A8 para acelerar a fase de computação. Se os problemas de memória só surgirem durante conversas longas, estime primeiro o termo do KV cache. Teste a quantização do KV cache quando esse termo dominar. Ative prefix caching quando os prefixos repetidos forem predominantes.
5. Algoritmos vs. kernels do runtime
Os algoritmos de quantização, como GPTQ ou AWQ, definem como os pesos do modelo são mapeados para uma precisão inferior. Os kernels do runtime, como Marlin ou os kernels personalizados do vLLM, são código GPU de baixo nível que executa a multiplicação de matrizes. Um modelo altamente comprimido só será rápido se existir um kernel otimizado para o seu formato de quantização específico.
O benchmark do vLLM da JarvisLabs em Qwen2.5-32B-Instruct com uma NVIDIA H200 torna visível o efeito do kernel:
| Quantização / kernel | Perplexidade, menor é melhor | Pass@1, maior é melhor | Throughput | TTFT |
|---|---|---|---|---|
| FP16 baseline | 6.56 | 56.1% | 461 tok/s | 57.7 ms |
| AWQ | 6.84 | 51.8% | 68 tok/s | 277.8 ms |
| GPTQ | 6.90 | 46.3% | 277 tok/s | 107.1 ms |
| Marlin-GPTQ | 6.97 | 45.7% | 712 tok/s | 51.9 ms |
| Marlin-AWQ | 6.84 | 51.8% | 741 tok/s | 73.5 ms |
| GGUF Q4_K_M | 6.74 | 51.8% | 93 tok/s | 958.0 ms |
| bitsandbytes | 6.67 | 51.8% | 168 tok/s | 135.3 ms |
Não copie estes números para a sua stack. Resultam de um modelo, uma classe de GPU e uma configuração de software específicos. Demonstram um ponto mais restrito: o nome do algoritmo no checkpoint não indica a velocidade do serving.
Por exemplo, AWQ e Marlin-AWQ utilizam os mesmos pesos de 4 bits. A implementação Marlin é muito mais rápida porque o seu kernel CUDA funde a dequantização e a multiplicação de matrizes numa única operação GPU altamente otimizada.
Faça benchmark do baseline e das variantes comprimidas com a mesma combinação de prompts e a mesma ferramenta. Inicie cada variante como servidor e atribua-lhe um nome de modelo estável na API; vllm bench serve envia pedidos para essa API em vez de carregar diretamente o checkpoint:
vllm serve ./outputs/Qwen2.5-32B-Instruct-AWQ-W4A16 \
--served-model-name qwen2.5-32b-awq \
--host 127.0.0.1 \
--port 8000
vllm bench serve \
--backend openai \
--base-url http://127.0.0.1:8000 \
--endpoint /v1/completions \
--model qwen2.5-32b-awq \
--dataset-name sharegpt \
--num-prompts 200 \
--input-len 1024 \
--output-len 256
Registe o throughput, TTFT, latência entre tokens, utilização de memória e qualidade das tarefas. Quando alguns destes indicadores evoluem em direções opostas, esse trade-off é precisamente o que precisa de observar antes de fazer ship.
O menu de algoritmos
Utilize esta tabela como mapa, não como ranking:
| Algoritmo | Formato comum | O que procura preservar | Principal custo |
|---|---|---|---|
| GPTQ | W4A16 | Reconstrução por layer com estimativas de Hessian | Calibração lenta e processamento mais complexo |
| AWQ | W4A16 / W4A8 | Canais de ativação importantes | Requer calibração e kernels de serving fused |
| SmoothQuant | W8A8 | Comportamento das ativações INT8, movendo a escala dos outliers para os pesos | Ajuste de escalas por modelo |
| QuaRot / SpinQuant | W4A4 / W4A8 | Menor pressão dos outliers de ativação através de rotações | Complexidade das rotações no runtime |
| HQQ | W4A16 / W2A16 | Compressão weight-only rápida sem calibração | A qualidade requer verificações downstream com larguras de bits muito baixas |
| QLoRA (NF4) | NF4 | Memória de treino dos adapters | Não é um bom default para serving |
| K-quants / IQ-quants GGUF do llama.cpp | Encodings de tensores mistos de poucos bits | Qualidade de inferência local por byte | Não foi concebido para serving cloud em batch |
A toolchain está a evoluir ativamente. O AutoGPTQ foi arquivado em abril de 2025, e o AutoAWQ foi arquivado e oficialmente deprecated em maio de 2025. Para novos checkpoints compressed-tensors consumidos pelo vLLM, comece pelo llm-compressor. Utilize o GPTQModel quando precisar do percurso GPTQ ativo com Marlin, Machete, opções de memória para MoE ou disk offload.
Pruning e distillation também reduzem o custo de serving através de workflows separados. A sparsity estruturada 2:4 remove pesos segundo um padrão que os sparse tensor cores da NVIDIA conseguem utilizar. A distillation treina um modelo student mais pequeno para imitar um modelo maior, o que pode funcionar bem em tarefas restritas. Inclua qualquer um destes percursos na shortlist apenas quando o projeto puder suportar o trabalho adicional de pruning ou treino.
6. A memória de serving é mais do que os pesos
O checkpoint comprimido representa apenas parte da footprint de memória do serving. Dimensione o runtime completo antes de decidir se a quantização dos pesos é suficiente. A PagedAttention identifica o KV cache como um termo importante da memória de serving.
A quantização offline pode ser limitada por layer. Ferramentas como llm-compressor podem carregar um bloco do transformer, executar a matemática de calibração e quantização, escrever o bloco comprimido e prosseguir. Isto mantém a memória GPU de pico mais próxima da maior layer ativa, mais os buffers de calibração. Continua a precisar de RAM de CPU e disco para o checkpoint de origem, mas a GPU nem sempre tem de manter o modelo BF16 completo.
A memória GPU de pico durante a quantização offline pode aproximar-se mais de:
O serving é mais exigente. O checkpoint comprimido completo tem de permanecer residente juntamente com o KV cache e os buffers do runtime. O KV cache cresce com o comprimento do contexto e o tamanho do batch ativo:
Onde:
- é o número de layers.
- é o número de attention heads key-value. A attention grouped-query reduz este valor ao permitir que muitos query heads partilhem menos KV heads.
- é a dimensão de cada head, frequentemente 128 ou 256.
- é o número de tokens do prompt mais os tokens gerados.
- é o batch ativo de serving.
- é 2 para BF16 ou FP16 e 1 para FP8 ou INT8. O modo FP8 KV cache do vLLM é o exemplo de serving stack utilizado neste artigo.
A quantização do KV cache altera o armazenamento, enquanto a reutilização altera a alocação
O KV cache pode ser quantizado durante a inferência. Cada passo de decode produz tensores de ativação K e V para o novo token. Um modelo W8A8 pode já utilizar FP8 ou INT8 na matemática de projeção suportada, mas a cache continua a ser um objeto de armazenamento separado.
Muitas stacks de serving mantêm esse objeto no dtype do modelo ou da cache. Para o alterar, ative um KV-cache dtype, utilize um checkpoint com escalas de cache ou escolha uma implementação de cache quantizada.
Quando a quantização do KV cache está ativa, o engine escreve as entradas como uma representação de menor precisão acompanhada de escalas. Posteriormente, a attention faz dequantize da cache dentro do kernel ou, em alguns backends, executa parte da operação de attention no domínio quantizado.
A documentação estável do Quantized KV Cache do vLLM expõe isto diretamente com kv_cache_dtype="fp8" ou --kv-cache-dtype fp8. O vLLM suporta formatos de cache FP8 E4M3 e E5M2, além de estratégias de escala por tensor e por attention head. Pode utilizar escalas predefinidas ou calibração por dataset através de llm-compressor. Com o FlashAttention 3, o vLLM também pode executar operações de attention no domínio FP8, quantizando as queries além das keys e values.
O TensorRT-LLM expõe a cache FP8 através de KvCacheConfig(dtype='fp8') e lista a cache KV FP8 e a cache KV NVFP4 como receitas de quantização separadas da quantização de pesos/ativações. O Hugging Face Transformers também tem um percurso QuantizedCache através de cache_implementation="quantized", com hqq a suportar formatos de cache int2, int4 e int8, e quanto a suportar int2 e int4.
A KV caching normal armazena keys e values anteriores para evitar recalculá-los. O prefix caching reutiliza blocos da cache entre pedidos com o mesmo prefixo. A PagedAttention reduz a fragmentação e melhora a alocação, enquanto o KV offload move blocos da cache entre níveis de memória. Estas combinações dependem do runtime. A QuantizedCache do Hugging Face não suporta offloading. O vLLM documenta a sua cache KV quantizada separadamente do prefix caching e de outras funcionalidades de gestão da cache. Verifique cada combinação no runtime que vai implementar.
O risco para a qualidade também difere do PTQ weight-only. A quantização do KV cache injeta erro no estado de attention lido em cada passo posterior do decode. Teste separadamente a recuperação em contexto longo, o comportamento multi-turn, a segurança e as recusas, a formatação de tool use e a latência da saída. KVQuant, KIVI e o estudo do KV cache FP8 do vLLM avaliam a quantização do KV cache como um problema próprio.
O tamanho do modelo e o comprimento do contexto, por si só, não determinam se a compressão da cache é melhor do que mais uma ronda de compressão dos pesos. Calcule os bytes da cache utilizando a equação acima, com o número de KV heads do modelo, a dimensão dos heads, o batch ativo e o dtype da cache. Compare depois esse resultado com os bytes poupados entre dois formatos de pesos identificados, como BF16 e INT4. Se a cache for maior, testar a quantização FP8 do KV cache pode libertar mais memória de serving do que voltar a reduzir os pesos.
7. O hardware restringe o menu
A footprint dos pesos é fácil de estimar a partir do número de parâmetros e da precisão de armazenamento, seguindo a mesma lógica de dimensionamento utilizada nas discussões sobre memória de serving em torno do KV cache:
| Tamanho do modelo | Pesos BF16 | Pesos FP8 / INT8 | Pesos INT4 |
|---|---|---|---|
| 7B / 8B | ~14-16 GB | ~7-8 GB | ~3,5-4 GB |
| 14B | ~28 GB | ~14 GB | ~7 GB |
| 32B / 34B | ~64-68 GB | ~32-34 GB | ~16-17 GB |
| 70B | ~140 GB | ~70 GB | ~35 GB |
| 109B MoE | ~218 GB no total | ~109 GB | ~55 GB |
Os modelos mixture-of-experts podem ativar menos parâmetros por token, mas o conjunto completo de pesos continua a ter de residir algures, a menos que o runtime suporte offload. A matriz de suporte de quantização do TensorRT-LLM trata as famílias de modelos MoE como alvos de deployment com receitas próprias suportadas.
O hardware de deployment restringe os formatos de quantização viáveis:
- O serving em CPU depende de instruções vetoriais como AVX-512 ou AMX. Um ficheiro GGUF carregado através de
llama.cppé o percurso prático. - O Apple Silicon utiliza memória unificada, pelo que os modelos locais podem usar um grande pool de RAM partilhada em vez de VRAM dedicada. GGUF e
llama.cppcontinuam a ser o percurso comum para runtimes locais, porque o GGUF foi concebido para executors GGML. - A NVIDIA Ampere suporta percursos de serving tensor-core INT8, mas não suporta matemática tensor-core FP8 W8A8 nativa. As escolhas comuns são quantização weight-only W4A16 ou INT8 estático, de acordo com a matriz de suporte de hardware do TensorRT-LLM.
- A NVIDIA Ada e Hopper suportam percursos de serving FP8 no TensorRT-LLM. Vale a pena testar o serving FP8 W8A8 nestas GPUs.
- A NVIDIA Blackwell acrescenta suporte para NVFP4 e microscaling, mas o percurso de software continua a ser importante. Trate as stacks iniciais de floating point de poucos bits como sensíveis à versão.
8. Calibração e avaliação antes do deployment
Um modelo que carrega passou um smoke test. O deployment requer verificações de qualidade e de serving para a workload-alvo. Avaliações recentes de quantização reportam resultados diferentes para serving de LLM, tarefas de contexto longo e modelos intensivos em reasoning.
Para a calibração, utilize prompts semelhantes aos da produção:
- Inclua traces RAG, queries SQL, históricos de agents, tarefas de código, payloads de tool calls e system prompts da workload-alvo. A PTQ estática depende de os dados de calibração corresponderem à distribuição de produção.
- Faça corresponder os comprimentos das sequências. Prompts curtos de uma única interação não expõem o comportamento das ativações em contexto longo.
- Mantenha
embed_tokenselm_headcom maior precisão, caso o método ou runtime o permita — um padrão comum de exclusão nas receitas do LLM Compressor. - Utilize amostras suficientes para estabilizar os intervalos de ativação. O exemplo de KV cache do vLLM define
NUM_CALIB_SAMPLES = 512. Considere isto um exemplo documentado, não uma contagem universal. O número adequado de amostras depende do método, modelo, comprimento da sequência e workload de produção. - Remova secrets e dados privados dos utilizadores antes de utilizar logs de produção.
Na avaliação, teste tanto a qualidade linguística como o comportamento de serving:
- A perplexidade num corpus padrão deteta degradação linguística geral, mas o benchmark da JarvisLabs é um lembrete útil de que a perplexidade e o throughput podem evoluir de forma diferente.
- As tarefas de domínio detetam falhas que a perplexidade oculta. Utilize HumanEval para programação, MMLU para conhecimento geral e AIME ou MATH-500 para reasoning matemático quando esses domínios forem relevantes.
- As verificações de formato são importantes para sistemas agentic. Teste a conformidade com JSON Schema, a saída em markdown, o formato dos tool calls e o comportamento de recusa, porque as avaliações de modelos quantizados podem não detetar falhas ao nível da aplicação mesmo quando a precisão agregada do benchmark parece estável.
- Os testes de contexto longo detetam danos causados pela quantização do KV cache. Needle-in-a-haystack é rudimentar, mas os resultados de quantização em contexto longo mostram por que razão estas verificações devem fazer parte do deploy gate.
- Os testes de carga devem reportar throughput, TTFT, latência entre tokens, capacidade máxima do batch e memória de pico. O vLLM expõe estas medições através de
vllm bench serve.
Avalie rigorosamente modelos intensivos em reasoning. A quantização sub-4-bit ou W4A4 sem rotações pode prejudicar a precisão do reasoning mesmo quando a perplexidade baseline parece estável, que é precisamente o alerta central do estudo sobre modelos de reasoning quantizados.
9. Workflow do repositório complementar
O repositório complementar, slavadubrov/model-compression-demo, pretende tornar o processo de decisão reproduzível. Utiliza uv e centra-se em planeamento, receitas, dry runs e configurações de benchmark baseadas nas mesmas fontes utilizadas aqui: vLLM, LLM Compressor, TensorRT-LLM e os artigos sobre os algoritmos.
O README público na revisão 8b45003849e830bed2ff341a9f027b017d932c1f foi verificado em 2026-08-16. O checkout complementar não está presente neste workspace, pelo que não pude executar aqui o seu CLI. Os comandos abaixo são ilustrativos até os executar a partir desse checkout pinned, e o plano de benchmark continua a precisar do hardware de serving-alvo.
Não copie a saída da receita FP8 dessa revisão pinned. O seu comando recipe --algorithm fp8-dynamic produz um modelo e um output path internamente inconsistentes. O comando continua omitido aqui até o repositório complementar ser corrigido.
Clone o repositório e inspecione os algoritmos suportados:
git clone https://github.com/slavadubrov/model-compression-demo.git
cd model-compression-demo
git checkout 8b45003849e830bed2ff341a9f027b017d932c1f
uv run python demo.py list-algorithms
Comece pelo planeamento e dimensionamento:
uv run python demo.py plan \
--model-preset qwen3-8b \
--goal fit-memory \
--hardware ampere \
--context 4096 \
--concurrency 4
uv run python demo.py estimate \
--model-preset qwen3-8b \
--scheme w4a16 \
--context 4096 \
--concurrency 4
uv run python demo.py plan \
--model-preset qwen3-0.6b \
--hardware cpu
Depois, gere uma receita e faça preview da quantização antes de gastar tempo de GPU:
uv run python demo.py recipe --algorithm gptq-w4a16
uv run python demo.py quantize --dry-run
uv run python demo.py quantize \
--algorithm gptq-w4a16 \
--model Qwen/Qwen3-8B \
--dry-run
Para o planeamento de serving e benchmarks:
uv run python demo.py serve-command \
--algorithm fp8-dynamic \
--fp8-kv-cache \
--enable-prefix-caching
uv run python demo.py benchmark-plan \
--model Qwen/Qwen3-8B \
--algorithms gptq-w4a16,rtn-w8a16,fp8-dynamic \
--dataset-name sharegpt \
--num-prompts 200 \
--input-len 1024 \
--output-len 256 \
--output-json reports/quantization-benchmark-plan.json
Por fim, compare os modelos base e comprimido com thresholds explícitos:
uv run python demo.py quality-eval \
--base-model Qwen/Qwen3-8B \
--compressed-model outputs/Qwen3-8B-W4A16 \
--mode all \
--lm-eval-task hellaswag \
--lm-eval-limit 50 \
--max-perplexity-delta-pct 5 \
--output-json reports/qwen3-8b-w4a16-quality.json
Execute o trabalho por ordem: planeie o alvo, estime a memória, faça dry run da receita, faça benchmark do serving e compare depois a qualidade com os thresholds. Esta sequência reflete a separação feita neste artigo entre dimensionamento de memória, benchmarking do runtime e avaliação de qualidade.
10. Os modelos de difusão requerem um percurso separado
Os pipelines de difusão e diffusion transformers têm um comportamento das ativações diferente do dos LLM autoregressivos. A SVDQuant trata a quantização de difusão como um problema separado de outliers nas ativações.
Os LLM autoregressivos geram um token de cada vez. Os modelos de difusão executam passos repetidos de denoising, e as suas distribuições de ativação mudam ao longo do processo. Uma passagem padrão de quantização de LLM a 4 bits pode poupar memória num modelo de difusão, mas introduzir artefactos visuais graves. Métodos específicos para difusão, como SVDQuant / Nunchaku e a quantização de difusão do NVIDIA ModelOpt, tratam esse padrão de ativação diferente.
Utilize as seguintes heurísticas conservadoras, não defaults universais. O pipeline, o componente, o modelo e o runtime requerem testes separados:
- Mantenha o VAE em 16 bits na primeira comparação. Esta heurística conservadora reduz uma fonte de artefactos de imagem. Teste menor precisão apenas quando o método e o pipeline-alvo o validarem.
- Experimente primeiro o backbone DiT ou U-Net, porque normalmente contém a maior parte dos parâmetros. Esta é uma heurística; verifique a memória, a latência e a qualidade da imagem para o pipeline-alvo. Os métodos de quantização de difusão adotam a mesma abordagem ao nível dos componentes.
- Trate os text encoders separadamente. Quantizar T5-XXL ou CLIP pode afetar o alinhamento com o prompt ou o rendering de texto num determinado pipeline, pelo que deve avaliá-los de forma independente em vez de assumir um comportamento genérico de transformer.
- Utilize métodos conscientes da difusão, como SVDQuant, quando os outliers de ativação forem o principal problema.
- Avalie com imagens, não com métricas de texto. Verifique a aderência ao prompt, o rendering de texto, os tons de pele, o equilíbrio de cores, o detalhe fino, a latência e a VRAM.
Se o conjunto de avaliação contiver apenas prompts simples ou comuns, irá falhar casos-limite. Inclua casos difíceis: texto pequeno, mãos, objetos repetidos, layouts estruturados e prompts com restrições negativas, porque as falhas de quantização de difusão aparecem visualmente e não na perplexidade de modelos de linguagem.
11. Defaults para produção
Para serving de LLM empresarial, comece com um baseline BF16 no engine de serving exato que planeia utilizar. Se o objetivo for throughput e o hardware o suportar, teste FP8 W8A8. Se o modelo não couber, teste AWQ ou GPTQ W4A16 com kernels da classe Marlin. Se o contexto longo ou a concorrência forem o problema, teste a quantização FP8 do KV cache. Se o problema forem prefixos repetidos, ative também prefix caching. Faça ship da versão comprimida apenas quando os benchmarks de qualidade e de serving passarem.
Para inferência local e edge, comece com um ficheiro GGUF utilizando Q4_K_M ou Q5_K_M. Passe para um GGUF Q8_0 quando a memória o permitir e a qualidade for mais importante do que a footprint. Descer abaixo de 4 bits deve ser o último recurso, não um default.
Para fine-tuning, utilize NF4 com QLoRA para treinar adapters de forma económica. Avalie o adapter na aplicação antes de fazer merge. Depois do merge, exporte para o artefacto de serving de que realmente precisa: um ficheiro GGUF compatível com llama.cpp, um checkpoint AWQ/GPTQ/compressed-tensors, um checkpoint de serving FP8 ou BF16.
Para difusão, comece por estas heurísticas conservadoras e teste visualmente cada combinação de pipeline/modelo/runtime. A perplexidade de texto não indica se um pipeline de imagens se degradou; utilize evidência específica de difusão, como SVDQuant, e avaliação visual.
Referências
- JarvisLabs vLLM Benchmarks: JarvisLabs, vLLM Quantization Complete Guide and Benchmarks, 2026. JarvisLabs.
- Hugging Face Optimum Quantization Guide: Hugging Face, Quantization conceptual guide. Docs.
- vLLM Quantization Docs: projeto vLLM, Quantization. Docs.
- vLLM Quantized KV Cache Docs: projeto vLLM, Quantized KV Cache. Docs.
- vLLM Benchmark Docs: projeto vLLM, vllm bench serve. Docs.
- LLM Compressor Docs: projeto vLLM, LLM Compressor. Docs.
- GPTQModel: ModelCloud, GPTQModel. GitHub.
- TensorRT-LLM Quantization: NVIDIA, TensorRT-LLM Quantization. Docs.
- NVIDIA NVFP4: NVIDIA, Introducing NVFP4 for Efficient and Accurate Low-Precision Inference. Blog.
- Hugging Face QuantizedCache: Hugging Face, Cache strategies: Quantized cache. Docs.
- NVIDIA Model Optimizer: NVIDIA, Model Optimizer. GitHub.
- torchao Quantization: PyTorch, torchao quantization overview. Docs.
- bitsandbytes Quantization: Hugging Face, bitsandbytes. Docs.
- HQQ: Dropbox, Half-Quadratic Quantization. GitHub.
- PEFT: Hugging Face, Parameter-Efficient Fine-Tuning. Docs.
- Ollama: runtime de modelos locais Ollama. Website.
- LM Studio: runtime local de AI LM Studio. Website.
- AutoGPTQ status: repositório AutoGPTQ, arquivado em abril de 2025. GitHub.
- AutoAWQ status: repositório AutoAWQ, arquivado e deprecated em maio de 2025. GitHub.
- GPTQ: Frantar et al., GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers, NeurIPS 2023. arXiv:2210.17323.
- Marlin: Frantar et al., MARLIN: Mixed-Precision Auto-Regressive Parallel Inference on Large Language Models, arXiv:2408.11743. arXiv:2408.11743.
- AWQ: Lin et al., AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration, MLSys 2024. arXiv:2306.00978.
- SmoothQuant: Xiao et al., SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models, ICML 2023. arXiv:2211.10438.
- QuaRot: Ashkboos et al., QuaRot: Outlier-Free 4-Bit Inference in Rotated LLMs, NeurIPS 2024. arXiv:2404.00456.
- SpinQuant: Meta AI Research, SpinQuant: LLM Quantization with Learned Rotations, arXiv:2405.16406. arXiv:2405.16406.
- QLoRA / NF4: Dettmers et al., QLoRA: Efficient Finetuning of Quantized LLMs, NeurIPS 2023. arXiv:2305.14314.
- SVDQuant / Nunchaku: MIT HAN Lab, SVDQuant: Absorbing Outliers by Low-Rank Components for 4-Bit Diffusion Models, ICLR 2025. arXiv:2411.05007, Nunchaku.
- vLLM PagedAttention: Kwon et al., Efficient Memory Management for Large Language Model Serving with PagedAttention, SOSP 2023. arXiv:2309.06180.
- Grouped-Query Attention: Ainslie et al., GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints, EMNLP 2023. arXiv:2305.13245.
- vLLM FP8 KV Cache: Kubler, Kurtic, Wilkinson et al., The State of FP8 KV-Cache and Attention Quantization in vLLM, vLLM Blog, abril de 2026. vLLM Blog.
- KIVI: Liu et al., KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache, ICML 2024. arXiv:2402.02750.
- KVQuant: Hooper et al., KVQuant: Towards 10 Million Context Length LLM Inference with KV Cache Quantization, NeurIPS 2024. arXiv:2401.18079.
- LLM Serving Evaluation: Kurtic et al., “Give Me BF16 or Give Me Death”? Accuracy-Performance Trade-Offs in LLM Quantization, ACL 2025. arXiv:2411.02355.
- Long-context Quantization Evaluation: Mekala et al., Does quantization affect models’ performance on long-context tasks?, arXiv:2505.20276. arXiv:2505.20276.
- Reasoning Evaluation: Quantization Hurts Reasoning? An Empirical Study on Quantized Reasoning Models, arXiv:2504.04823. arXiv:2504.04823.
- SlideSparse: SlideSparse: Fast and Flexible (2N-2):2N Structured Sparsity, arXiv:2603.05232v1. arXiv:2603.05232v1.
- HumanEval: OpenAI, HumanEval. GitHub.
- MMLU: Hendrycks et al., Measuring Massive Multitask Language Understanding. arXiv:2009.03300.
- MATH-500: Hugging Face H4, MATH-500. Dataset.
- GGUF and llama.cpp: ggml-org, GGUF file format e llama.cpp. GGUF, llama.cpp.
- Hugging Face GGUF Docs: Hugging Face, GGUF. Docs.
- Reference Repository: slavadubrov/model-compression-demo.