Cuantización GGUF: Q4_K_M vs Q8_0, tamaño y VRAM

Niveles de cuantización GGUF comparados: Q4_K_M vs Q8_0 en tamaño, VRAM y calidad, y la regla — Q4_K_M por defecto, solo subes para código y matemáticas.

HUMANpor @mrsaynothing43d7 min de lectura

Elige Q4_K_M por defecto; sube a Q6_K o Q8_0 cuando te sobre VRAM y necesites el último par de por ciento de calidad. La cuantización GGUF encoge los pesos de un modelo desde los 16 bits a menos — Q4_K_M guarda unos 4.85 bits por peso, así que un modelo 7B baja de ~14 GB a ~4.1 GB con una perplejidad que normalmente empeora menos del 1% respecto al original. La pregunta "qué cuantización gguf usar" tiene una respuesta aburridamente estable que casi todo el drama online oculta. Abajo: la tabla completa de niveles — de Q2_K a Q8_0, tamaño, VRAM y pérdida de calidad medida — el cálculo de tamaño hecho por ti, y un comando para medir el daño en tu propio hardware en vez de fiarte del benchmark de un desconocido. Si el quant va hacia vLLM en vez de llama.cpp, can vLLM run GGUF tiene el plugin y la regla de solo GPU.

¿Qué hace realmente la cuantización GGUF?

Un modelo se entrena en punto flotante de 16 bits (FP16 o BF16): cada uno de sus miles de millones de pesos es un número de 2 bytes. La cuantización comprime cada peso a menos bits. La forma ingenua — redondear cada peso a un entero de 4 bits — destruye los valores pequeños pero importantes, así que GGUF usa dos trucos:

  1. Escalado por bloques. Los pesos se agrupan en bloques (normalmente de 32) y cada bloque recibe su propio factor de escala. Los valores de 4 bits son desplazamientos dentro de ese bloque, así que sobrevive un rango amplio de magnitudes.
  2. K-quants conscientes de la importancia. La "K" en Q4_K_M significa super-bloques de escalas, más tratar las capas de atención y feed-forward de forma distinta entre sí, porque toleran la compresión de manera desigual.

La familia "I" (IQ4_XS y compañía) va más allá con codebooks de teoría de la información prestados de la compresión de imágenes. Misma idea, codificación más elaborada: menos bits por peso a calidad similar, al costo de una inferencia algo más lenta en algunos backends.

Una aclaración que evita la mayoría de la confusión: la cuantización cambia solo los pesos almacenados. Arquitectura, tokenizador y manejo de contexto quedan intactos. Un archivo Q4 y un archivo Q8 del mismo modelo son el mismo modelo con distinto abrigo.

¿Q4 vs Q8: más cuantización es mejor?

Técnicamente sí; perceptualmente no. Usando como referencia las corridas de perplejidad del propio llama.cpp sobre modelos Llama: Q8_0 queda a ~0.02% de FP16 — para cualquier propósito práctico, sin pérdida. Q6_K es casi indistinguible. Q4_K_M gana unos 1–2% de perplejidad, Q4_0 un poco más, y Q2_K es donde las respuestas coherentes empiezan a desarmarse en modelos pequeños.

Dos reglas que los números implican:

  • El tamaño del modelo compra margen para cuantizar. Un modelo 70B sobrevive Q2/Q3 mucho mejor que un 7B, porque los modelos grandes son más redundantes. Cuantizar un 7B a Q2 es una amputación; cuantizar un 70B a Q3 es sastrería.
  • El piso de calidad se mueve con la tarea. El chat tolera Q4. La generación exacta de código, las matemáticas y el RAG sobre documentos precisos exponen antes el ruido de la cuantización. Si un modelo Q4 sigue escribiendo código sutilmente equivocado, prueba el mismo modelo en Q6_K antes de culpar al modelo.
Nivel Bits/peso Tamaño vs FP16 Pérdida de calidad Úsalo cuando
Q2_K ~3.4 ~21% Severa en sub-13B Cuando nada más cabe, solo modelos grandes
Q3_K_M ~3.9 ~25% Notable VRAM justa, modelos ≥14B
Q4_K_S ~4.6 ~29% Pequeña Q4_K_M no cabe y estás cerca
Q4_K_M ~4.85 ~30% ~1% de perplejidad El default. Mejor compromiso calidad/tamaño
Q5_K_M ~5.7 ~35% ~0.5% VRAM disponible, tareas críticas de calidad
Q6_K ~6.6 ~41% Casi nula Código/matemáticas, aún cabe cómodo
Q8_0 ~8.5 ~53% Prácticamente ninguna Corridas de referencia, bases para fine-tune
IQ4_XS ~4.3 ~27% ≈Q4_K_M Q4_K_M apenas no cabe y el backend soporta i-quants

¿Cuánta VRAM necesita cada nivel?

Haz el cálculo de tamaño tú mismo en vez de memorizar tablas — es una línea:

size_GB ≈ (bits_per_weight × params) / 8
# modelo 8B @ Q4_K_M: 4.85 × 8 / 8 ≈ 4.9 GB
# modelo 8B @ Q8_0:   8.50 × 8 / 8 ≈ 8.5 GB

Luego suma las partes que la fórmula deja fuera: el KV cache (crece con la longitud de contexto — de unos cientos de MB a varios GB), las activaciones y los buffers de cómputo. Margen práctico: un modelo "de 4.9 GB" quiere una tarjeta de 6 GB a contexto 4k, y flash-attention más cuantización del KV cache para seguir ahí a 16k. Los pesos son el titular, no la factura completa.

¿Qué cuantización GGUF deberías usar?

Orden de decisión, sin excepciones que valga la pena memorizar:

  1. Calcula primero tu presupuesto de contexto + KV, luego los pesos. Un contexto que no cabe es peor que una calidad que no puedes medir.
  2. Default a Q4_K_M. Es el default de la comunidad por algo — cerca del 1% de perplejidad por el 70% del tamaño. Cada registro, incluido el de Ollama, lo trae como baseline.
  3. Sube a Q6_K cuando la tarea castiga el ruido: código, matemáticas, extracción, cualquier cosa que le pasas a un pipeline sin supervisión.
  4. Q8_0 solo para referencia — tests A/B, medición del daño de cuantización o una base para fine-tune. Como driver diario lo único que compra es calor en tus sensores de VRAM.
  5. Baja de Q4 solo a la fuerza, y solo en modelos grandes. Pruébalo con un prompt conocido por difícil antes de fiarte.

Si estás eligiendo qué archivo bajar de Hugging Face, prefiere un Q4_K_M.gguf único sobre splits fragmentados, salvo que quien lo subió solo publique estos últimos — menos piezas móviles. Y si estás eligiendo dónde correrlo, la elección de motor es un eje aparte: mira llama.cpp vs Ollama para eso.

¿Cómo mides el daño de la cuantización tú mismo?

Los benchmarks difieren; tu prompt es constante. Compila llama.cpp una vez, descarga dos niveles del mismo modelo y mide tanto la perplejidad (menor es mejor) como los tokens/segundo:

git clone https://github.com/ggml-org/llama.cpp && cd llama.cpp
cmake -B build && cmake --build build --config Release -j

huggingface-cli download bartowski/Meta-Llama-3.1-8B-Instruct-GGUF \
  Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf Meta-Llama-3.1-8B-Instruct-Q8_0.gguf \
  --local-dir models

# perplejidad sobre un trozo de wiki-text (más bajo = más cerca del modelo original)
./build/bin/llama-perplexity -m models/Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf -ngl 99
./build/bin/llama-perplexity -m models/Meta-Llama-3.1-8B-Instruct-Q8_0.gguf  -ngl 99

# y velocidad en el mismo hardware
./build/bin/llama-bench -m models/Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf -ngl 99

El número de Q4_K_M será unas centésimas de punto peor que el de Q8_0 y el archivo será ~40% más pequeño. Si tu tarea downstream no nota la diferencia — y para la mayoría no la nota — tienes tu respuesta sin leer el leaderboard de nadie.

¿La cuantización daña la privacidad o el argumento de solo-local?

No — es aritmética sobre pesos, completamente offline, y el archivo cuantizado es solo un contenedor más pequeño de los mismos parámetros. Correr un Q4_K_M local filtra exactamente lo mismo (o poco) que correr el modelo de precisión completa local: nada sale de la máquina. La variable relevante para la privacidad es dónde corre la inferencia, no el ancho de bits. Los caveat habituales sobre la procedencia del modelo aplican igual a cada nivel de quant: un fine-tune "uncensored" con base robada en Q8 no es más seguro que los mismos pesos en Q4. Para el lado del formato de archivo, mira cómo correr modelos GGUF localmente.

¿Qué nivel deberías elegir?

Q4_K_M, y deja de leer foros sobre el tema. Sube a Q6_K para trabajo hambriento de precisión si la VRAM alcanza, mantén un Q8_0 a mano para comparaciones A/B y trata todo lo que esté bajo Q4 como ración de emergencia solo para modelos grandes. El único error que vale evitar es simétrico: preocuparse por Q4-vs-Q5 mientras se ignora la longitud de contexto, que ha roto más setups locales que cualquier quant en la historia.