GRATÍCULAinstrumento de maestría
BancoRTX 5090 · GB202
Rev2026.06
Entrar
N1 · Serving world-class/L4

Cuantización para serving: FP8, AWQ y NVFP4

Objetivo de maestría

cuantizar un modelo a varias precisiones, servirlo, y medir tú el tradeoff calidad/velocidad/VRAM — incluyendo NVFP4, la frontera de Blackwell. Y sortear las trampas reales que hacen perder horas con NVFP4 en una 5090.


4.1El mapa de formatos (qué es cada uno y cuándo)

FormatoBits peso / activaciónHardwareUso típico
BF16/FP1616 / 16universalbaseline de calidad
FP8 (E4M3)8 / 8Hopper, Blackwellmejor calidad entre los cuantizados; densos ≤30B en 5090
AWQ4 / 16universalweight-only; muy usado; buena calidad
GPTQ4 / 16universalweight-only; alternativa a AWQ
GGUF Q4_K_M~4 / 16llama.cpp/Ollamalocal/edge, CPU+GPU
MXFP44 / 4 (microscaled)BlackwellMoE grandes (gpt-oss-120B)
NVFP44 / 4 (microscaled NVIDIA)Blackwell (SM100+)máximo throughput W4A4 con calidad ~FP8

Distinción que la gente confunde:

  • Weight-only (AWQ/GPTQ): solo los pesos van en 4-bit; las activaciones siguen en 16-bit. Reduce VRAM y banda de pesos (ayuda al decode memory-bound), pero el matmul sigue en alta precisión.
  • W4A4 (NVFP4/MXFP4): pesos y activaciones en 4-bit → el matmul corre en los Tensor Cores FP4 nativos de Blackwell → throughput ~2× sobre FP8. Es el salto que tu 5090 puede dar y la mayoría de GPUs no.

Importante para la 5090: es SM_120 (≥SM100), así que ejecuta cuantización de activaciones NVFP4 (W4A4 completo). En GPUs <SM100 vLLM solo haría weight-only aunque cargues un checkpoint NVFP4.


4.2La vía rápida: checkpoints NVFP4 ya hechos

NVIDIA y la comunidad publican modelos pre-cuantizados bajo el namespace nvidia/...-NVFP4 y en RedHatAI. Si tu modelo está, no necesitas calibrar nada:

bash
1# Servir un NVFP4 ya cuantizado en la 5090
2vllm serve nvidia/Llama-3.1-8B-Instruct-NVFP4
3# (densos y MoE soportados; para MoE NVFP4 activa el kernel FlashInfer)
4# VLLM_USE_FLASHINFER_MOE_FP4=1 vllm serve <moe-nvfp4-model>

Trampas NVFP4 reales (te ahorran horas):

  • No pases --quantization a mano. Distintos publicadores declaran el formato distinto (NVIDIA usa modelopt, RedHatAI usa compressed-tensors). Si fuerzas --quantization modelopt sobre un checkpoint compressed-tensors, obtienes ValueError: ...does not match.... Deja que vLLM autodetecte desde config.json.
  • Backend Marlin produce salida vacía en algunas combinaciones: si pides 20 tokens y salen strings vacíos, es este bug → revisa versión de vLLM / no fuerces backend.
  • MoE NVFP4 en modelos nuevos (p.ej. Gemma 4) puede requerir una versión dev de vLLM donde se mapean bien las scale keys del FusedMoE; si el loader no mapea, actualiza vLLM.

4.3La vía manual: cuantizar tú con llm-compressor (NVFP4)

Para tus propios fine-tunes (Nivel 2) necesitarás cuantizar tú. llm-compressor es la herramienta oficial integrada con vLLM.

python
1# lab_n1l4_nvfp4.py — cuantiza un modelo a NVFP4 con calibración (PTQ)
2from llmcompressor import oneshot
3from llmcompressor.modifiers.quantization import QuantizationModifier
4from transformers import AutoModelForCausalLM, AutoTokenizer
5from datasets import load_dataset
6
7MODEL_ID = "Qwen/Qwen3-8B"
8model = AutoModelForCausalLM.from_pretrained(MODEL_ID, torch_dtype="auto")
9tok = AutoTokenizer.from_pretrained(MODEL_ID)
10
11# Datos de calibración: muestras representativas de tu dominio real de uso.
12ds = load_dataset("HuggingFaceH4/ultrachat_200k", split="train_sft[:512]")
13def to_text(ex): return {"text": tok.apply_chat_template(ex["messages"], tokenize=False)}
14ds = ds.map(to_text)
15
16recipe = QuantizationModifier(targets="Linear", scheme="NVFP4", ignore=["lm_head"])
17
18oneshot(
19    model=model, dataset=ds, recipe=recipe,
20    max_seq_length=2048, num_calibration_samples=512,
21)
22SAVE_DIR = MODEL_ID.split("/")[-1] + "-NVFP4"
23model.save_pretrained(SAVE_DIR, save_compressed=True)
24tok.save_pretrained(SAVE_DIR)
25print("Listo:", SAVE_DIR, "→ sírvelo con: vllm serve", SAVE_DIR)

Líneas no triviales:

  • Datos de calibración representativos: PTQ ajusta las escalas observando activaciones reales. Si calibras con datos muy distintos a tu uso, las escalas serán subóptimas → más degradación. Usa muestras de tu dominio.
  • scheme="NVFP4": pide W4A4 microscaled de NVIDIA. ignore=["lm_head"]: la capa de salida es sensible; mantenerla en alta precisión preserva calidad (patrón estándar).
  • save_compressed=True: guarda en el formato que vLLM carga directamente.

4.4Lo no negociable: evaluar la degradación

Cuantizar sin medir calidad es fe, no ingeniería. Compara cada formato contra BF16 en una métrica que te importe.

python
1# lab_n1l4_eval.py — evalúa degradación de calidad entre precisiones
2# Usa lm-eval-harness para una métrica estándar (MMLU subset) + tu propia tarea.
3# pip install lm-eval
4#
5#   lm_eval --model vllm \
6#     --model_args pretrained=Qwen/Qwen3-8B,dtype=bfloat16 \
7#     --tasks mmlu --num_fewshot 5 --limit 500
8#
9#   lm_eval --model vllm \
10#     --model_args pretrained=./Qwen3-8B-NVFP4 \
11#     --tasks mmlu --num_fewshot 5 --limit 500
12#
13# Compara los dos accuracy. Repite para FP8 y AWQ. Construye la tabla de 4.5.

Para tu tarea propia (lo que de verdad te importa), evalúa con un conjunto de prompts representativo y un juez (exact match, o un LLM-as-judge local). La degradación aceptable depende de la tarea: tool-calling y razonamiento son más sensibles que chat abierto.


4.5La tabla que produces (entregable de la lección)

Formatotok/s decodetok/s agregado@32VRAMMMLUmi-tarea
BF16
FP8
AWQ
NVFP4

Con esta tabla respondes la pregunta que importa: ¿en qué punto la cuantización deja de pagar para mi caso? Esa decisión, defendida con tus números, es Nivel 3 de la rúbrica.


4.6Ejercicios

E1. Cuantiza Qwen3-8B a NVFP4 con el lab; sírvelo y mide tok/s vs BF16 y vs FP8. ¿Se acerca al ~2× sobre FP8 que promete W4A4?

E2. Evalúa MMLU de los cuatro formatos. ¿Cuánta accuracy pierdes en NVFP4? ¿Es aceptable para chat? ¿Y para una tarea de razonamiento?

E3. Provoca a propósito el error does not match pasando --quantization equivocado, reconócelo, y arréglalo dejando autodetectar. (Reconocer la trampa vale más que evitarla.)

4.7Trampas comunes

  • Pasar --quantization manual a un NVFP4 → mismatch de formato.
  • Calibrar con datos no representativos → degradación evitable.
  • Cuantizar y no evaluar calidad.
  • Asumir que <SM100 hace W4A4 (no; solo weight-only). Tu 5090 sí lo hace.

4.8Referencias

  • Docs llm-compressor (vLLM): "fp4 Quantization with NVFP4". Spheron, "FP4 Quantization on Blackwell GPUs". Papers AWQ (Lin et al. 2023), GPTQ (Frantar et al. 2022), "Pretraining LLMs with NVFP4" (NVIDIA 2025).