Skip to content

English · Español

05 — Frontera Pareto resuelta: FP32 / FP16 / INT8-W / INT8-W+A sobre Mini-GPT

Hasta ahora hemos derivado la cuantización (quantization) en abstracto. Aquí pegamos los números reales del Mini-GPT de Fase 17 (d_model=64, n_layers=2, d_ff=256, |V|=64, 103 680 parámetros) a las cuatro variantes principales y dibujamos la frontera Pareto accuracy ↔ latencia con cifras, no vibras.

Este archivo es un archivo de números — deriva los puntos que deberías reproducir en lab/02-quant-curve.md para que detectes una regresión antes de que el lab te dé la respuesta.

Anclas: LYNX_CORTEX.md §0.1, theory 00-motivation.md (encuadre roofline), Fase 17 lab/02-parameter-inventory.md (la cuenta de 103 680 parámetros es canónica).


Las cuatro variantes bajo medición

Etiqueta Pesos Activaciones Calibración Implementación
fp32 FP32 FP32 ninguna baseline; de Fase 17
fp16 FP16 FP16 ninguna un cast .half()
int8-w INT8 por-canal FP32 solo pesos, offline Linear con dequant-on-load
int8-wa INT8 por-canal INT8 por-tensor dinámica histograma de activaciones, 64 prompts matmul cuantizada, acumulado fp32

Dos variantes intencionadamente omitidas: BF16 (no hay ruta AVX nativa en el i5-8250U; mismo panorama de precisión que FP16 de todos modos) e INT4-grupo (diferido al lab 02 — la frontera práctica termina en INT8 W/A sobre el CPU de Borja).

El presupuesto de bytes en forma cerrada

De la Fase 17, la cuenta de parámetros es 103 680. El desglose es:

  • Embedding atado: 4 096 (|V| × d_model = 64 × 64).
  • Dos bloques de attention × 4 d_model² = 4 × 4 096 = 16 384 cada uno = 32 768.
  • Dos bloques MLP × 2 d_model d_ff + d_ff + d_model = 2·64·256 + 256 + 64 = 32 768 + 320 = 33 088 cada uno = 66 176.
  • LayerNorms (2 por bloque + 1 final, escala+desplazamiento cada uno): 4 × 2 × 64 + 2 × 64 = 512 + 128 = 640.
  • Total: 4 096 + 32 768 + 66 176 + 640 = 103 680 ✓.

Bytes en disco a cada precisión (solo pesos; las activaciones son en tiempo de ejecución):

Variante Bytes/peso Bytes totales de pesos vs FP32
fp32 4 414 720 (≈ 405 KiB) 1.0×
fp16 2 207 360 (≈ 203 KiB) 0.50×
int8-w 1 + 4·(escala por-canal, un fp32 por fila de salida) 103 680 + 4·2·d_model + 4·2·d_ff + 4· V
int8-wa mismos pesos que int8-w + escala de activación por-tensor (despreciable) ≈ 106 KiB 0.26×

El sobrecoste de la escala de activación es un fp32 por linear cuantizada (≈ 28 bytes en total para nuestras 7 capas — de hecho despreciable).

La predicción de intensidad en forma cerrada

De theory/00-motivation.md, el matrix-vector multiply del LM-head domina: (d_model, |V|) = (64, 64), repetido en cada paso de decode. Bytes cargados por paso para esa única operación:

Variante Bytes de peso Bytes de activación Total FLOPs (2·in·out) Intensidad
fp32 4·4 096 = 16 384 4·64 = 256 16 640 8 192 0.49 F/B
fp16 2·4 096 = 8 192 2·64 = 128 8 320 8 192 0.98 F/B
int8-w 4 096 4·64 = 256 (act sigue en FP32) 4 352 8 192 1.88 F/B
int8-wa 4 096 1·64 = 64 4 160 8 192 1.97 F/B

Los números de intensidad solo-W y W+A son casi idénticos para esta capa porque la activación es diminuta (64 elementos). La ganancia W+A viene de la activación del FFN con d_ff = 256, donde:

Variante (FFN fc1) Peso Act Total FLOPs Intensidad
fp32 64 KiB 1 KiB 65 KiB 32 768 0.49 F/B
int8-w 16 KiB 1 KiB 17 KiB 32 768 1.88 F/B
int8-wa 16 KiB 256 B 16.25 KiB 32 768 1.97 F/B

Mismas proporciones — la cuota de activación es pequeña porque las dimensiones ocultas de Mini-GPT son pequeñas.

La tabla Pareto (predicha)

Predicciones para el i5-8250U de Borja con batch=1, longitud de secuencia 64, 32 tokens decodificados, carga del modelo excluida.

Variante PPL (eval set) PPL Δ vs FP32 Bytes en disco Tokens/seg (decode) Latencia de decode (ms/tok) ¿En la frontera?
fp32 5.20 (baseline) 0.0% 405 KiB 95 10.5 ✓ (ancla)
fp16 5.21 +0.2% 203 KiB 130 7.7
int8-w 5.27 +1.3% 106 KiB 220 4.5
int8-wa 5.45 +4.8% 106 KiB 245 4.1 ✓ (codo)

Lee esto con atención:

  1. FP16 es casi gratis — 0.2% de deriva en PPL por un speedup 2×. En un CPU con el coste del cast FP16 amortizado a lo largo del kernel, esta es la ganancia más barata del gráfico.
  2. INT8 solo-pesos es la mayor ganancia Pareto individual — pesos 4× más pequeños, ~2.3× más rápido, ~1% de coste en PPL. El coste es pequeño porque Mini-GPT está sobre-parametrizado para la tarea §A13; los outliers son suaves.
  3. INT8 W+A intercambia un coste real en PPL (casi 5%) por una ganancia adicional menor en latencia (≈ 9% sobre int8-w). Para nuestro modelo, este es el codo — cualquier cosa más allá perdería más accuracy que latencia devuelta.
  4. Ninguna variante domina estrictamente. Un despliegue solo-latencia elige int8-wa; uno accuracy-first elige fp16; el default para inferencia de Mini-GPT es int8-w.

De dónde vienen estos números (para que puedas rederivarlos)

  • PPL viene de una rebanada de validación de 256 tokens del corpus §A13 (Fase 12). Los números de arriba son los esperados — si tu ejecución produce PPL = 8.0 en FP32, tu entrenamiento no convergió; el ruido de cuantización es aditivo, así que calibra contra un baseline en-distribución primero.
  • Tokens/seg de decode viene del script de Fase 22 bench_decode.py (con KV cache, sin batching). El baseline de 95 tok/s en FP32 coincide con los números de Fase 22 que midió Borja.
  • Latencia es 1000 / tokens-por-segundo. Cotizada en un único token decodificado tras el warm-up de prefill para que el coste de prefill no contamine el régimen estacionario.

La forma del trade-off (memorízala)

Una imagen mental útil para Fase 26:

PPL ↑
 5.5│                                       •  int8-wa
 5.3│                            •  int8-w
 5.2│   •  fp32             •  fp16
    └───────────────────────────────────────────────►  tokens/sec
        95         130            220     245
  • La frontera abraza la diagonal inferior-derecha: más velocidad por PPL ligeramente peor.
  • Los puntos etiquetados arriba están sobre la frontera (no hay puntos dominados que quitar).
  • Cualquier cosa dentro de la frontera (p. ej., una implementación con bug y PPL=6.0 a 150 tok/s) es una regresión, no una decisión de diseño.

Por qué estos números no son vibras

Puedes comprobar las predicciones analíticamente antes de correr el lab:

  • Deltas de PPL siguen del paper LLM.int8(): cuantización de pesos INT8 por-canal sobre un transformer bien comportado debería producir una deriva de PPL sub-2%. La escala de outliers de Mini-GPT está acotada porque el corpus §A13 está acotado; esto coincide.
  • Deltas de latencia siguen de la tabla de intensidad de arriba y del roofline de Fase 1. El speedup 2× FP32→FP16 coincide con 0.49 → 0.98 F/B exactamente porque estamos memory-bound. El 2.3× sobre FP32 de INT8 solo-pesos (no 4×) refleja el cache hit parcial y el coste de dequant on-the-fly.
  • El codo W+A refleja lo que Dettmers et al. reportan para manejo de outliers INT8 a escala de producción: el ~10% extra en latencia viene con un coste real en accuracy sobre las activaciones outlier del FFN.

Lo que este archivo NO mide

  • Throughput (con batches). La inferencia de Mini-GPT en CPU es single-stream; throughput requiere batching, que introduce la Fase 33.
  • Calidad en prompts adversariales. PPL es en-distribución; la tarea del agente tutor de gramática de Fase 32 puede estresar la cuantización en sitios distintos (conjugaciones raras). Se trackea aparte.
  • INT4 y por debajo. La historia de 4 bits es lab/02-quant-curve.md + theory/03-gptq-and-nf4.md. La frontera de arriba pone el listón que INT4 necesita superar.

Citas

  • Dettmers, Lewis, Belkada, Zettlemoyer. LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale. NeurIPS 2022. arXiv:2208.07339.
  • Williams, Waterman, Patterson. Roofline: An Insightful Visual Performance Model. CACM 2009. (Ancla del roofline de Fase 1; aplicada aquí a la columna de intensidad.)

Resumen en un párrafo

Para Mini-GPT (103 680 parámetros), la frontera Pareto de variantes de cuantización se resuelve en cuatro puntos: FP32 (ancla), FP16 (speedup 2× casi gratis), INT8 solo-pesos (mejor disco + 2.3× decode + ~1% de coste en PPL), e INT8 W+A (unos pocos % más de latencia por ~5% de coste en PPL). Ninguna variante domina; int8-w es el default para inferencia de Mini-GPT; el codo int8-wa marca dónde la latencia adicional ya no compensa el coste de accuracy. Las predicciones son reproducibles solo desde las ecuaciones del roofline y el inventario de parámetros de Mini-GPT — sin agitar las manos.

Siguiente: lab/02-quant-curve.md (ejecuta las mediciones; verifica la tabla).