DEV Community

João André Gomes Marques
João André Gomes Marques

Posted on

NexusQuant: compressão de memória para LLMs — guia prático

NexusQuant: compressão de memória para LLMs — guia prático

Neste guia vamos explorar os três presets de qualidade do NexusQuant em detalhe: quando usar cada um, o que esperar em termos de qualidade, e como o comportamento muda consoante o domínio do texto.

Instalação rápida

pip install "nexusquant-kv[hf]"
Enter fullscreen mode Exit fullscreen mode

Os três presets explicados

high — Compressão conservadora (10x)

O preset high é o ponto de entrada seguro. Remove apenas os tokens de menor impacto e quantiza com margens confortáveis.

from nexusquant import nexusquant_evict

with nexusquant_evict(model, quality="high"):
    output = model.generate(input_ids, max_new_tokens=512)
Enter fullscreen mode Exit fullscreen mode

Quando usar:

  • RAG com documentos técnicos ou legais onde a precisão importa
  • Q&A sobre código-fonte
  • Qualquer tarefa onde erros factuais têm custo real
  • Primeiro deploy em produção (começa aqui, mede, depois sobe)

O que esperar:

  • PPL +0.4% — praticamente imperceptível
  • 10x compressão — 128K → 1.3M tokens em 80 GB
  • Comportamento estável em contextos curtos e longos

balanced — O ponto ideal (17x)

with nexusquant_evict(model, quality="balanced"):
    output = model.generate(input_ids, max_new_tokens=512)
Enter fullscreen mode Exit fullscreen mode

Quando usar:

  • Sumarização de documentos longos
  • Chatbots com histórico de conversa longo
  • Análise de código com contexto alargado
  • A maioria dos casos de uso em produção

O que esperar:

  • PPL +1.3% — ligeiro, normalmente não notável pelo utilizador final
  • 17x compressão — 128K → 2.2M tokens em 80 GB
  • Bom equilíbrio entre memória e qualidade

max — Compressão máxima (33x)

with nexusquant_evict(model, quality="max"):
    output = model.generate(input_ids, max_new_tokens=512)
Enter fullscreen mode Exit fullscreen mode

Quando usar:

  • Processamento em batch onde throughput é mais importante que qualidade perfeita
  • Exploração de documentos muito longos (busca, triagem)
  • Investigação e benchmarking
  • Contextos onde o utilizador tolera alguma degradação

O que esperar:

  • PPL +2.6% — notável, especialmente em texto criativo
  • 33x compressão — 128K → 4.2M tokens em 80 GB
  • Pode haver omissões em detalhes específicos do contexto

Sensibilidade por domínio

O mesmo preset comporta-se de forma diferente consoante o tipo de texto. Em linhas gerais:

Domínio Sensibilidade Preset recomendado
Código / técnico Baixa balanced ou max
Académico / científico Baixa balanced
Jornalístico / factual Média high ou balanced
Criativo / narrativo Alta high
Jurídico / contratual Alta high

Texto estruturado (código, JSON, tabelas) é mais robusto ao eviction porque a estrutura local preserva o contexto. Texto narrativo depende mais de referências de longo alcance que podem ser evictadas.

Prefixes curtos: cuidado

O scorer de importância precisa de sinal suficiente para distinguir tokens relevantes de irrelevantes. Com menos de ~500 tokens, os resultados são menos fiáveis.

# Mau: prefix curto
input_ids = tok("O que é machine learning?", return_tensors="pt").input_ids
# ~6 tokens — o scorer não tem sinal suficiente

# Bom: context rico
long_prompt = document_text + "\n\nPergunta: O que é machine learning?"
input_ids = tok(long_prompt, return_tensors="pt").input_ids
# 800+ tokens — o scorer funciona bem
Enter fullscreen mode Exit fullscreen mode

Detetar regressão no teu workload

Antes de fazer deploy, corre uma comparação rápida:

import math
from nexusquant import nexusquant_evict

def perplexity(model, tok, text, device="cpu"):
    """Calcula perplexidade de um texto."""
    ids = tok(text, return_tensors="pt").input_ids.to(device)
    with torch.no_grad():
        loss = model(ids, labels=ids).loss
    return math.exp(loss.item())

baseline_ppl = perplexity(model, tok, your_domain_text)

for preset in ["high", "balanced", "max"]:
    with nexusquant_evict(model, quality=preset):
        ppl = perplexity(model, tok, your_domain_text)
    delta = (ppl - baseline_ppl) / baseline_ppl * 100
    print(f"{preset}: PPL {ppl:.2f} ({delta:+.2f}%)")
Enter fullscreen mode Exit fullscreen mode

Se o delta for aceitável para o teu caso de uso, avança com esse preset.

Exemplo completo: sumarização de documento longo

from transformers import AutoModelForCausalLM, AutoTokenizer
from nexusquant import nexusquant_evict
import torch

model = AutoModelForCausalLM.from_pretrained(
    "TinyLlama/TinyLlama-1.1B-Chat-v1.0",
    torch_dtype=torch.float16,
    device_map="auto",
)
tok = AutoTokenizer.from_pretrained("TinyLlama/TinyLlama-1.1B-Chat-v1.0")

# Documento longo (substitui pelo teu)
document = open("relatorio_anual.txt").read()
prompt = document + "\n\nResumo executivo em 3 pontos:\n"

input_ids = tok(prompt, return_tensors="pt").input_ids.to(model.device)
print(f"Tokens no prompt: {input_ids.shape[1]}")

# Compressão 17x — ideal para sumarização
with nexusquant_evict(model, quality="balanced"):
    output = model.generate(
        input_ids,
        max_new_tokens=200,
        do_sample=False,
        temperature=1.0,
    )

resume = tok.decode(output[0][input_ids.shape[1]:], skip_special_tokens=True)
print(resume)
Enter fullscreen mode Exit fullscreen mode

Notebook interativo no Colab

Podes correr todos estes exemplos no teu browser, sem GPU, em menos de 2 minutos:

github.com/jagmarques/nexusquant/blob/main/examples/nexusquant_demo.ipynb

Resumo

  • Começa sempre com quality="high" e mede no teu domínio
  • balanced é o sweet spot para a maioria dos casos em produção
  • max é para quando o throughput importa mais que qualidade perfeita
  • Prefixes curtos degradam mais — dá contexto suficiente ao scorer
  • Texto criativo/narrativo é mais sensível que texto técnico/estruturado

Cumprimentos, João Marques

Top comments (0)