This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.
Un modelo de 70B en FP16 necesita 140GB. Dos A100s solo para los pesos. Cuantiza a FP8: una GPU de 80GB. INT4: un MacBook.
Tipo: Build
Idiomas: Python (con numpy)
Prerrequisitos: Fase 10, Lecciones 01-10 (LLMs desde Cero)
Tiempo: ~120 minutos
Objetivos de Aprendizaje
Implementar cuantización simétrica y asimétrica de FP16 a INT8 e INT4, incluyendo escalado por tensor y por canal
Calcular el ahorro de memoria de la cuantización y determinar qué precisión se adapta a la VRAM de una GPU dada
Explicar la diferencia entre la cuantización post-entrenamiento (PTQ) y el entrenamiento consciente de la cuantización (QAT)
Aplicar GPTQ o AWQ para cuantizar un modelo real y medir la relación de compromiso entre precisión y memoria en un benchmark
El Problema
Llama 3 70B tiene 70 mil millones de parámetros. Cada parámetro es un número de punto flotante de 16 bits. Eso es 140 mil millones de bytes. 140GB. Una sola A100 tiene 80GB de VRAM. Ni siquiera se pueden cargar los pesos, y mucho menos ejecutar la inferencia, en una sola GPU. Se necesitan dos A100 a
/hora cada una solo para servir un modelo.
Pero 16 bits por parámetro es un desperdicio. La mayoría de los pesos en una red neuronal se agrupan cerca de cero. El rango dinámico completo de FP16 (de 0.000000059 a 65,504) está casi completamente sin usar. Si se mide la distribución real de los pesos en Llama 3 70B, el 95% de ellos cae entre -0.1 y +0.1. Se están quemando 16 bits para representar valores que podrían caber en 4.
La cuantización reemplaza números de alta precisión por otros de menor precisión. FP16 a FP8 corta la memoria a la mitad. FP16 a INT4 la reduce a una cuarta parte. Ese modelo de 140GB se convierte en 35GB. Cabe en una sola GPU de consumo. Si se llega a la cuantización de 2 bits (agresiva, con pérdidas, pero utilizable para algunas tareas), el mismo modelo se ejecuta en una computadora portátil de 16GB.
El costo es la precisión. Cada bit que se elimina destruye información. La pregunta es cuánta precisión se pierde y dónde. Un modelo INT4 bien cuantizado conserva el 95-99% de la calidad del original en la mayoría de los benchmarks. Una cuantización ingenua a INT4 puede destruir el modelo por completo. La diferencia es la técnica.
Las cuantizaciones de la comunidad de Llama 3 a INT4 con GPTQ muestran aproximadamente 1-2 puntos de perplejidad perdidos en WikiText. Mistral lanzó checkpoints en FP8 de Mixtral 8x22B con cero pérdida de calidad medible en MMLU. El formato GGUF impulsa llama.cpp, ejecutando modelos de 70B en MacBooks con chips de la serie M. La cuantización no es un truco. Es la ruta de despliegue estándar para cualquier modelo mayor de 7B.
El Concepto
Formatos de Números: Qué Hace Cada Bit
Cada número de punto flotante tiene tres partes: signo, exponente y mantisa (también llamada significando). El signo es un bit. El exponente determina el rango (qué tan grande o pequeño puede ser el número). La mantisa determina la precisión (cuántos decimales se obtienen).
FP32 es precisión completa. 23 bits de mantisa otorgan aproximadamente 7 dígitos decimales de precisión. Rango: aproximadamente 1.2 x 10^-38 a 3.4 x 10^38. El entrenamiento solía ocurrir exclusivamente en FP32. Todavía ocurre para la acumulación (sumas consecutivas durante la multiplicación de matrices).
FP16 reduce a la mitad los bits. 10 bits de mantisa otorgan aproximadamente 3.3 dígitos decimales. El exponente se reduce a 5 bits, disminuyendo drásticamente el rango (valor máximo ~65,504). Esto está bien para los pesos (que se agrupan cerca de cero) pero es peligroso para las activaciones y los gradientes que pueden dispararse durante el entrenamiento. El entrenamiento en FP16 requiere el escalado de pérdida para evitar el desbordamiento negativo (underflow).
BF16 (Brain Float 16) mantiene el exponente de 8 bits de FP32 pero reduce la mantisa a 7 bits. Mismo rango que FP32, menor precisión que FP16. Google lo diseñó específicamente para el aprendizaje profundo. La intuición: el rango importa más que la precisión para las redes neuronales. Un gradiente de 10^-20 que sufre desbordamiento negativo a cero en FP16 sobrevive en BF16. Un peso de 0.07342 que se redondea a 0.0734 en BF16 es lo suficientemente cercano. Cada ejecución de entrenamiento moderna utiliza BF16 o una combinación de BF16/FP32.
FP8 viene en dos variantes. E4M3 (4 exponentes, 3 mantisas) se utiliza para pesos y activaciones durante la inferencia. E5M2 (5 exponentes, 2 mantisas) se utiliza para gradientes durante el entrenamiento, donde el rango importa más que la precisión. La inferencia en FP8 en GPUs H100 logra una aceleración del 30-50% sobre FP16 con una pérdida de calidad insignificante.
INT8 es un formato de número entero. Sin exponente, sin mantisa. Solo 256 valores espaciados uniformemente de -128 a 127. Se necesita un factor de escala para mapear pesos de punto flotante a este rango. La ventaja: la aritmética de enteros es más rápida y más eficiente energéticamente que la de punto flotante. La multiplicación de matrices INT8 en una A100 se ejecuta a 624 TOPS en comparación con los 312 TFLOPS de FP16.
INT4 va más allá. Solo 16 valores posibles. El factor de escala hace el trabajo pesado. La calidad depende completamente de cómo elija la escala y qué pesos cuantice. Los métodos INT4 de última generación (GPTQ, AWQ) conservan más del 95% de la calidad original del modelo.
graph LR
subgraph Formats["Panorama de Formatos de Números"]
direction TB
FP32["FP32\n32 bits\n4 bytes/param\nEstándar de oro de entrenamiento"]
BF16["BF16\n16 bits\n2 bytes/param\nPredeterminado de entrenamiento"]
FP16["FP16\n16 bits\n2 bytes/param\nLínea base de inferencia"]
FP8["FP8\n8 bits\n1 byte/param\n30-50% más rápido"]
INT8["INT8\n8 bits\n1 byte/param\n2x rendimiento (throughput)"]
INT4["INT4\n4 bits\n0.5 bytes/param\n4x compresión"]
end
FP32 -->|"entrenamiento"| BF16
BF16 -->|"inferencia"| FP16
FP16 -->|"nativo de H100"| FP8
FP16 -->|"despliegue en servidor"| INT8
FP16 -->|"borde/laptop"| INT4
style FP32 fill:#1a1a2e,stroke:#0f3460,color:#fff
style BF16 fill:#1a1a2e,stroke:#0f3460,color:#fff
style FP16 fill:#1a1a2e,stroke:#ffa500,color:#fff
style FP8 fill:#1a1a2e,stroke:#51cf66,color:#fff
style INT8 fill:#1a1a2e,stroke:#51cf66,color:#fff
style INT4 fill:#1a1a2e,stroke:#e94560,color:#fff
Cómo Funciona la Cuantización
La operación principal es simple. Tome un tensor de valores de punto flotante, encuentre un factor de escala, multiplique, redondee al entero más cercano y almacene los enteros más el factor de escala.
El error es el error de redondeo. Cada valor puede diferir como máximo en scale / 2. El error total en una capa depende de cuántos pesos tenga y de qué tan sensible sea el modelo a las perturbaciones en esos pesos.
Cuantización por tensor vs. por canal. La cuantización por tensor utiliza un solo factor de escala para toda la matriz de pesos. Simple pero con pérdidas: si una columna tiene valores grandes y otra tiene valores pequeños, los valores pequeños pierden la mayor parte de su precisión. La cuantización por canal utiliza un factor de escala por canal de salida (por fila o columna de la matriz de pesos). Más sobrecarga (se almacenan N factores de escala en lugar de 1) pero una calidad drásticamente superior. Cada método de cuantización en producción utiliza granularidad por canal o más fina.
La cuantización asimétrica agrega un desplazamiento de punto cero: quantized = round(tensor / scale) + zero_point. Esto maneja distribuciones que no están centradas en cero. Las activaciones ReLU, por ejemplo, siempre son no negativas. La cuantización simétrica desperdicia la mitad del rango de enteros en valores negativos que nunca aparecen. La cuantización asimétrica mapea el rango real [min, max] al rango completo de enteros.
Jerarquía de Sensibilidad
No todo en un modelo tolera la cuantización por igual. Hay una jerarquía clara.
Pesos (más robustos). Los pesos del modelo cambian lentamente durante el entrenamiento y siguen una distribución aproximadamente gaussiana centrada cerca de cero. Se cuantizan fácilmente. Los pesos INT8 con escalas por canal producen resultados casi sin pérdidas. INT4 requiere métodos más sofisticados pero funciona.
Activaciones (sensibilidad moderada). Las activaciones son los valores intermedios que fluyen a través de la red durante la inferencia. Tienen un rango dinámico más amplio que los pesos y contienen valores atípicos (outliers). Una sola cabeza de atención puede producir valores de activación 100 veces mayores que la media. Estos outliers son críticos para la calidad del modelo. Cuantizarlos ingenuamente destruye información. Soluciones: mantener los canales de outliers en mayor precisión (LLM.int8()), usar escalas de activación por token o por canal.
KV cache (alta sensibilidad). El caché clave-valor (KV cache) almacena los estados de atención para todos los tokens anteriores. En la mayoría de las longitudes de contexto largas, el KV cache domina la memoria. Para un modelo de 70B con un contexto de 32K, el KV cache por sí solo es de 40GB en FP16. Cuantizar el KV cache a FP8 o INT8 ahorra una cantidad masiva de memoria, pero cualquier error se acumula en todos los cálculos de atención futuros. El impacto en la calidad se escala con la longitud de la secuencia.
Logits de atención (más sensibles). El softmax en la atención es altamente sensible a pequeños cambios en sus entradas. Un error de cuantización de 0.01 en un logit previo al softmax puede desviar la distribución de atención de manera significativa. La mayoría de los esquemas de cuantización mantienen el cálculo de la atención en una precisión mayor (FP16 o BF16) incluso cuando todo lo demás está cuantizado.
graph TD
subgraph Sensitivity["Sensibilidad de Cuantización (Baja a Alta)"]
direction LR
W["Pesos\nGaussiano, cerca de cero\nINT4 funciona bien"]
A["Activaciones\nRango más amplio, outliers\nINT8 con cuidado"]
KV["KV Cache\nLos errores se acumulan\nFP8 o INT8"]
ATT["Logits de Atención\nSoftmax amplifica el error\nMantener en FP16"]
end
W -->|"seguro"| A
A -->|"cuidadoso"| KV
KV -->|"peligroso"| ATT
style W fill:#1a1a2e,stroke:#51cf66,color:#fff
style A fill:#1a1a2e,stroke:#ffa500,color:#fff
style KV fill:#1a1a2e,stroke:#e94560,color:#fff
style ATT fill:#1a1a2e,stroke:#ff0000,color:#fff
PTQ vs. QAT
La Cuantización Post-Entrenamiento (PTQ) cuantiza un modelo ya entrenado. Sin reentrenamiento. Se toman los pesos de FP16, se calculan los factores de escala, se redondea y se despliega. Rápido (minutos a horas) y económico. Funciona bien para INT8 y FP8. Para INT4, la PTQ ingenua a menudo falla gravemente porque se acumulan los errores de redondeo. Los métodos avanzados de PTQ (GPTQ, AWQ) utilizan datos de calibración para minimizar el error de cuantización.
El Entrenamiento Consciente de la Cuantización (QAT) inserta operaciones de cuantización simuladas (fake quantization) en el paso hacia adelante (forward pass) durante el entrenamiento. El modelo aprende a colocar sus pesos donde los errores de redondeo son pequeños. Los gradientes fluyen a través de la cuantización simulada utilizando el estimador de paso directo (straight-through estimator - STE): se pretende que la operación de redondeo tiene un gradiente de 1. QAT produce mejores modelos INT4 e INT2 que PTQ pero requiere una ejecución de entrenamiento completa. Google utilizó QAT para el servicio eficiente de Gemini. Meta utilizó QAT para algunos objetivos de despliegue de Llama.
Aspecto
PTQ
QAT
Costo
Minutos a horas
Ejecución de entrenamiento completa
Calidad en INT8
Excelente (< 0.1% de pérdida)
Excelente
Calidad en INT4
Buena con GPTQ/AWQ (1-3% de pérdida)
Mejor (< 1% de pérdida)
Calidad en INT2
Deficiente
Utilizable para algunas tareas
Datos de calibración
128-1024 ejemplos
Conjunto de datos de entrenamiento completo
Cuándo usar
Despliegue, iteración
Calidad máxima a un ancho de bits bajo
GPTQ, AWQ, GGUF
GPTQ (GPT Quantization) es un método PTQ de un solo paso (one-shot). Cuantiza los pesos capa por capa, utilizando un pequeño conjunto de datos de calibración (128 ejemplos es lo típico) para medir la Hessiana (información de segundo orden sobre qué tan sensible es la salida a cada peso). Los pesos que la Hessiana indica que son importantes se cuantizan con más cuidado. GPTQ fue el primer método en hacer práctica la cuantización INT4 para LLMs. TheBloke en Hugging Face popularizó GPTQ al lanzar versiones cuantizadas de cientos de modelos.
AWQ (Activation-Aware Weight Quantization) observa que una pequeña fracción de los pesos (alrededor del 1%) son desproporcionadamente importantes porque se multiplican con grandes valores de activación. AWQ identifica estos pesos sobresalientes utilizando datos de calibración y los escala hacia arriba antes de la cuantización (luego reduce proporcionalmente las activaciones correspondientes). Esto mantiene los pesos importantes en un rango donde la cuantización INT4 sea precisa. AWQ típicamente iguala o supera ligeramente la calidad de GPTQ mientras es 1.5-2 veces más rápido de aplicar.
GGUF (GPT-Generated Unified Format) es el formato de archivo utilizado por llama.cpp y su ecosistema. Admite cuantización mixta: diferentes capas obtienen diferentes anchos de bits. La primera y la última capa (embedding y cabeza de salida/output head) se mantienen típicamente en una precisión mayor. Las capas intermedias obtienen INT4 o INT3. Los archivos GGUF son autónomos: pesos, tokenizador y metadados, todo en un solo archivo. El formato está diseñado para la inferencia en CPU y Apple Silicon, donde cargar todo el modelo en la memoria y ejecutar multiplicaciones de matrices en la CPU o Metal GPU es la ruta estándar. Q4_K_M es la variante de cuantización GGUF más popular, equilibrando calidad y tamaño.
graph TD
subgraph Methods["Métodos de Cuantización"]
direction TB
GPTQ_["GPTQ\nGuiado por Hessiana\nOptimización por capa\nPopular en HuggingFace"]
AWQ_["AWQ\nConsciente de activación\nEscalado de pesos sobresalientes\n1.5-2x más rápido que GPTQ"]
GGUF_["GGUF\nPrecisión mixta\nOptimizado para CPU + Metal\nEcosistema llama.cpp"]
end
subgraph Use["Mejor Para"]
GPU["Inferencia en GPU\n(CUDA, ROCm)"]
EDGE["Borde / Laptop\n(CPU, Metal)"]
end
GPTQ_ --> GPU
AWQ_ --> GPU
GGUF_ --> EDGE
style GPTQ_ fill:#1a1a2e,stroke:#ffa500,color:#fff
style AWQ_ fill:#1a1a2e,stroke:#51cf66,color:#fff
style GGUF_ fill:#1a1a2e,stroke:#0f3460,color:#fff
Medición de Calidad
¿Cómo sabe si su modelo cuantizado sigue siendo bueno?
Perplejidad (Perplexity). La métrica más común. Menor es mejor. Calcule la perplejidad en un conjunto de datos reservado (WikiText-2 es el estándar) tanto para el modelo original como para el cuantizado. El delta le indica cuánta información destruyó la cuantización. Reglas generales: delta < 0.5 es excelente, 0.5-1.0 es bueno, 1.0-2.0 es aceptable para la mayoría de las tareas, > 2.0 significa que algo salió mal.
Benchmarks específicos de tareas. Ejecute el modelo cuantizado en MMLU, HumanEval, GSM8K o su suite de evaluación personalizada. Compare contra el original. La cuantización afecta diferentes capacidades de manera desigual. Las tareas de matemáticas y codificación son más sensibles a la pérdida de precisión que las de conocimiento general.
Comparación de salidas. Generes respuestas de ambos modelos en los mismos prompts y compare. LLM como juez (LLM-as-judge - Lección 10) funciona bien aquí. Calcule una tasa de victorias: ¿en qué fracción de prompts el modelo cuantizado iguala o supera al original?
Latencia y rendimiento (throughput). La cuantización existe para hacer que los modelos sean más rápidos y económicos. Mida los tokens por segundo, el tiempo hasta el primer token y el uso de memoria. Un modelo cuantizado que sea más lento que el original es peor que inútil.
Modelo
Formato
Tamaño
Perplejidad (WikiText-2)
MMLU
Tokens/seg (A100)
Llama 3 70B
FP16
140GB
3.12
79.5%
38
Llama 3 70B
FP8
70GB
3.14
79.3%
55
Llama 3 70B
GPTQ INT4
35GB
4.32
77.8%
72
Llama 3 70B
AWQ INT4
35GB
4.18
78.1%
75
Llama 3 70B
GGUF Q4_K_M
40GB
4.25
77.9%
28 (CPU)
El patrón: FP8 es casi gratuito. INT4 cuesta 1-2 puntos de MMLU pero duplica el rendimiento y reduce la memoria a una cuarta parte. La relación de compromiso vale la pena para casi cualquier despliegue.
Números Reales
FP16 a FP8 en H100: 30-50% de aceleración de inferencia, < 0.1% de pérdida de calidad. Esta es la cuantización obvia. Cada despliegue en H100 debería usarla.
FP16 a INT8 (LLM.int8()): reducción de memoria de 2x, < 0.5% de pérdida de calidad. El enfoque de precisión mixta mantiene las características atípicas (outliers) en FP16 mientras cuantiza todo lo demás a INT8.
FP16 a INT4 (GPTQ/AWQ): reducción de memoria de 4x, 1-3% de pérdida de calidad según el modelo y el método. Permite modelos de 70B en una sola GPU de 48GB.
FP16 a INT4 (GGUF Q4_K_M): reducción de memoria de 3.5x, 1-2% de pérdida de calidad. Optimizado para inferencia en CPU. Un modelo de 70B en Q4_K_M tiene aproximadamente 40GB y se ejecuta a 10-15 tokens/segundo en un M3 Max con 64GB.
FP16 a INT2: reducción de memoria de 8x, 5-15% de pérdida de calidad. Solo es viable para tareas específicas y limitadas donde se pueda tolerar la degradación. Frontera de investigación, no listo para producción para uso general.
Constrúyelo
Paso 1: Representaciones de Formatos Numéricos
Construya la representación a nivel de bits de cada formato para ver exactamente qué hacen el signo, el exponente y la mantisa.
Mida cuánta información destruye la cuantización. Error cuadrático medio, relación señal-ruido y similitud de coseno entre los tensores original y reconstruido.
Paso 4: Barrido de Ancho de Bits (Bit-Width Sweep)
Cuantice el mismo tensor en diferentes anchos de bits (2, 3, 4, 8, 16) y mida la calidad en cada nivel. Esto muestra exactamente dónde está la caída abrupta de calidad (quality cliff).
Simule la cuantización de diferentes partes de un transformer y mida qué componentes son los más sensibles. Esto demuestra la jerarquía de sensibilidad: pesos < activaciones < KV cache < atención.
GPTQ cuantiza una columna a la vez, utilizando la Hessiana para decidir cómo distribuir el error de redondeo. Esta es una versión simplificada que captura la idea principal: utilizar datos de calibración para medir la importancia del peso, luego cuantizar los pesos menos importantes de manera más agresiva.
def simulated_gptq(weight_matrix, calibration_inputs, num_bits=4):
n_in, n_out = weight_matrix.shape
qmin = -(2 ** (num_bits - 1))
qmax = 2 ** (num_bits - 1) - 1
H = np.zeros((n_in, n_in))
for x in calibration_inputs:
x = x.reshape(-1, 1) if x.ndim == 1 else x
for row in range(x.shape[0]):
xi = x[row].reshape(-1, 1)
H += xi @ xi.T
H /= len(calibration_inputs)
H += np.eye(n_in) * 1e-4
weight_importance = np.diag(H)
quantized = np.zeros_like(weight_matrix, dtype=np.int32)
scales = np.zeros(n_out)
errors = np.zeros(n_out)
W = weight_matrix.copy()
for col in range(n_out):
w_col = W[:, col]
abs_max = np.max(np.abs(w_col))
if abs_max == 0:
scales[col] = 1.0
continue
scale = abs_max / qmax
scales[col] = scale
q_col = np.clip(np.round(w_col / scale), qmin, qmax).astype(np.int32)
quantized[:, col] = q_col
quant_error = w_col - q_col * scale
errors[col] = np.sqrt(np.mean(quant_error ** 2))
if col < n_out - 1:
importance_weights = weight_importance / (np.max(weight_importance) + 1e-10)
for next_col in range(col + 1, min(col + 4, n_out)):
compensation = quant_error * importance_weights * 0.1
W[:, next_col] += compensation
return quantized, scales, {"column_errors": errors,
"mean_error": float(np.mean(errors)),
"max_error": float(np.max(errors))}
def dequantize_gptq(quantized, scales):
result = np.zeros_like(quantized, dtype=np.float64)
for col in range(quantized.shape[1]):
result[:, col] = quantized[:, col] * scales[col]
return result
Paso 7: Simulación de AWQ
AWQ identifica los pesos sobresalientes (aquellos que se multiplican con grandes activaciones) y los protege mediante el escalado antes de la cuantización.
vLLM admite de forma nativa modelos AWQ y GPTQ. Maneja la descuantización durante la multiplicación de matrices y utiliza atención paginada (paged attention) para el KV cache. Para FP8 en H100, agregue --dtype float8_e4m3fn.
Entrégalo
Esta lección produce outputs/skill-quantization.md, un marco de decisión para elegir la estrategia de cuantización correcta. Dado el tamaño de su modelo, el hardware de destino y los requisitos de calidad, le indica qué formato, método y pasos de validación utilizar. Incluye cálculos de presupuesto de memoria, recomendaciones de precisión por componente y recetas de despliegue para vLLM, llama.cpp y TensorRT-LLM.
Ejercicios
Implementar cuantización grupal. En lugar de una escala por canal, utilice una escala por grupo de 128 pesos dentro de un canal. Esto es lo que GPTQ y AWQ realmente utilizan. Compare tamaños de grupo de 32, 64, 128 y 256 en la misma matriz de pesos. Los grupos más pequeños brindan mejor calidad pero mayor sobrecarga de almacenamiento para los factores de escala.
Construir un cuantizador de precisión mixta. Cuantice la primera y la última capa de una red multicapa en INT8 mientras cuantiza las capas intermedias en INT4. Compare la calidad de salida de extremo a extremo frente a INT4 uniforme e INT8 uniforme. Mida el ahorro de memoria en comparación con todo en INT8.
Implementar el estimador de paso directo (STE) para el entrenamiento consciente de la cuantización. Inserte operaciones simuladas de cuantización/descuantización en el paso hacia adelante de una red simple de dos capas entrenada en una tarea de regresión. Compare la pérdida final entre un modelo entrenado normalmente (luego PTQ a INT4) frente a un modelo entrenado con QAT desde el principio.
Construir un cuantizador consciente de outliers inspirado en LLM.int8(). Detecte canales donde la magnitud de la activación supere 6 veces la media. Mantenga esos canales en FP16 y cuantice todo lo demás a INT8. Mida la calidad de extremo a extremo en la capa del transformer del Paso 5 con diferentes umbrales de outliers (3x, 6x, 10x).
Implementar un panel (dashboard) de calidad de cuantización. Dada una matriz de pesos, calcule y muestre: el histograma de distribución de pesos, la distribución del error de cuantización, los factores de escala por canal, los canales peor cuantizados (mayor error de reconstrucción) y la similitud de coseno entre las saídas originales y cuantizadas en 100 entradas aleatorias. Identifique qué canales deben mantenerse con mayor precisión.
Términos Clave
Término
Lo que la gente dice
Lo que realmente significa
FP16
"Media precisión"
Flotante de 16 bits con 5 bits de exponente y 10 bits de mantisa, valor máximo 65,504, formato estándar de inferencia
BF16
"Brain float"
Flotante de 16 bits con 8 bits de exponente (mismo rango que FP32) y 7 bits de mantisa, diseñado por Google para el entrenamiento
FP8
"Flotante de ocho bits"
Dos variantes: E4M3 (inferencia, más precisión) y E5M2 (entrenamiento, más rango), nativo en H100
INT8
"Entero de ocho bits"
256 valores espaciados uniformemente de -128 a 127, necesita un factor de escala para mapear desde flotantes
INT4
"Entero de cuatro bits"
16 niveles en total, requiere métodos sofisticados (GPTQ, AWQ) para mantener la calidad
Cuantización por canal
"Una escala por fila"
Utiliza un factor de escala separado para cada canal de salida en lugar de uno para todo el tensor, reduce drásticamente el error
GPTQ
"El método Hessiano"
Cuantización post-entrenamiento que utiliza información de segundo orden para minimizar el error de salida, una capa a la vez
AWQ
"Consciente de activación"
Escala los pesos sobresalientes (aquellos multiplicados por grandes activaciones) antes de la cuantización para protegerlos
GGUF
"El formato llama.cpp"
Archivo de modelo autónomo con capas de precisión mixta, optimizado para inferencia en CPU y Apple Silicon
PTQ
"Cuantizar después del entrenamiento"
Convierte los pesos de un modelo entrenado a una precisión menor sin reentrenamiento, rápido pero limitado en compresión extrema
QAT
"Cuantizar durante el entrenamiento"
Inserta la cuantización simulada en el paso hacia adelante para que el modelo aprenda a tolerar el redondeo, mejor en INT4/INT2
Datos de calibración
"Los 128 ejemplos"
Un pequeño conjunto de datos ejecutado a través del modelo para calcular estadísticas de activación para establecer factores de escala
Factor de escala
"El multiplicador"
Convierte entre el rango de punto flotante y el rango de enteros: float_val = int_val * scale
Delta de perplejidad
"Qué tan peor"
Diferencia en perplejidad entre el modelo original y el cuantizado, < 0.5 es excelente, > 2.0 es un problema