HSAQ / HSAQ_FORMATO.md
MethodWhite's picture
HSAQ: documentación limpia (Qué es/Qué NO es, HSAQ v2 aparte) + implementación + scripts abliteración
dc9acb9 verified
|
Raw
History Blame Contribute Delete
7.9 kB

HSAQ — HyperSparse Adaptive Quantization

¿Qué es? ✅

Cuantización y poda adaptativa de activaciones (máscara binaria por kthvalue, umbral por lote, máscaras aprendibles, STE, SGD Nesterov).

¿Qué NO es? ❌

No es cuantización de pesos (INT8/INT4/GPTQ/AWQ/bitsandbytes). Opera solo sobre activaciones, no sobre pesos.

HSAQ v2 — aparte ⚠️

Extensión experimental (cuantización de pesos INT8/INT4) del paper de M.A.T.E.R.I.A. V4; separada de esta definición core.

Definición Formal

HSAQ es un mecanismo de cuantización de activaciones vía sparsity adaptativa. La "cuantización" refiere a que las activaciones se reducen a {0, valor} mediante una máscara binaria dinámica calculada por batch.

No es cuantización de pesos. No es INT8/INT4. No es bitsandbytes. HSAQ opera exclusivamente sobre activaciones, no sobre pesos.


1. Algoritmo

Entrada: x ∈ ℝ^(B×T×D)  (batch de activaciones)
Parámetro: sparsity ∈ [0,1)

  flat = |x|.reshape(B, -1)       # Magnitudes por batch
  n = flat.size(1)                 # Total de neuronas
  k = n * (1 - sparsity)           # Neuronas a mantener (top-K%)
  thresh = kthvalue(flat, k)       # Umbral dinámico por batch
  mask = |x| >= thresh             # Máscara binaria {0, 1}
  return x * mask                  # ~30% de activaciones → 0

1.1 Propiedades clave

Propiedad Descripción
Adaptativo El umbral kthvalue se recalcula en cada batch
Por elemento Cada neurona se evalúa individualmente contra el umbral
Hardware-agnostic Solo usa torch.abs, reshape, kthvalue, multiplicación
Gradiente fluye STE implícito: el gradiente pasa por las neuronas activas
Sin estado No hay buffers persistentes entre batches

1.2 Parámetros

Parámetro Default Función
sparsity 0.3 Fracción de activaciones a enmascarar (0.3 = 30%)

Éste es el único parámetro de HSAQ. Todo lo demás (weight_bits, AWQ, etc.) son externos y no forman parte del mecanismo central.


2. HSAQ como Optimizer

HSAQ reemplaza a AdamW como mecanismo de optimización.

2.1 Por qué funciona

  1. La máscara sparse (kthvalue) selecciona las neuronas más activas por batch
  2. El gradiente solo fluye por las neuronas no enmascaradas
  3. Esto crea un regularización adaptativa: las neuronas irrelevantes no reciben gradiente
  4. El umbral dinámico evita la necesidad de momentum/estados de optimizer

2.2 Optimizer externo

Se usa SGD Nesterov (momentum=0.9) para actualizar pesos:

HSAQ + SGD Nesterov = optimizer completo
  ├── HSAQ: máscara sparse adaptativa (regularización dinámica)
  └── SGD: actualización de pesos con momentum

No se usa AdamW. SGD con momentum tiene solo 1 estado de optimizer por parámetro (vs 2 de AdamW), ahorrando 4 bytes por parámetro.

2.3 Hyperparámetros recomendados

Parámetro Valor Razón
sparsity 0.3 Balance cómputo/precisión
lr 5e-4 Tasa de aprendizaje
momentum 0.9 Nesterov momentum
weight_decay 0.01 Regularización L2
clip_grad_norm 1.0 Estabilidad

3. Pipeline de Entrenamiento (con HSAQ por capas)

1. Embedding → HSAQ (sparsity 30%)
2. Transformer Block 1 → HSAQ (sparsity 30%)   ← umbral propio
3. Transformer Block 2 → HSAQ (sparsity 30%)   ← umbral propio
4. Transformer Block N → HSAQ (sparsity 30%)   ← umbral propio
5. SNN + SSM → JEPA → Head → logits

Cada capa tiene su propio umbral dinámico calculado via kthvalue. Esto permite que:

  • Capas tempranas (bajo nivel) tengan patrones de activación distintos
  • Capas tardías (alto nivel) se especialicen en representaciones más abstractas
  • El modelo aprenda qué información preservar en cada nivel
  • Diferentes distribuciones de activación por capa no afecten el umbral global

3.1 Forward con HSAQ por capas

h = Embedding(x)         # [B, T, dim]
h = HSAQ(h)               # Sparsity post-embedding

for layer in transformer:
    h = layer(h)           # Forward del transformer block
    h = HSAQ(h)            # Sparsity por capa (umbral propio)

h = SNN(h)                 # Neuronas de pulsos
h = SSM(h)                 # State Space Model
h = JEPA(h)                # Espacio latente
h = Head(h)                # Logits finales
1. Forward pass
   ├── Token Embedding → ℝ^(B×T×D)
   ├── HSAQ sparsity → 30% de activaciones → 0
   ├── Transformer Blocks (GQA + RoPE + SwiGLU)
   ├── LIF-SNN (neuronas de pulsos)
   ├── SSM (State Space Model)
   ├── JEPA Encoder → espacio latente
   └── Head → logits

2. Backward pass
   └── Gradiente fluye solo por activaciones activas (STE nativo)

3. Weight update
   └── SGD Nesterov (momentum 0.9)

4. No es HSAQ (cosas que NO pertenecen)

Componente Motivo de exclusión
INT8/INT4 weight quantization HSAQ cuantiza activaciones, no pesos
bitsandbytes 8-bit Adam HSAQ reemplaza a AdamW
AWQ calibration Es post-training, no parte de HSAQ
GPTQ Es compresión de pesos, ortogonal a HSAQ
BPE tokenizer HSAQ funciona con char-level
Weight tying Es optimización de arquitectura, no de HSAQ

5. Código Mínimo

class HSAQ(nn.Module):
    """HyperSparse Adaptive Quantization — sparsity adaptativa"""
    def __init__(self, sparsity=0.3):
        super().__init__()
        self.sparsity = sparsity

    def forward(self, x):
        flat = x.abs().view(x.size(0), -1)    # Magnitudes
        k = int(flat.size(1) * (1 - self.sparsity))  # Top-K
        thresh = torch.kthvalue(flat, k, dim=1).values  # Umbral dinámico
        thresh = thresh.view(-1, *([1] * (x.dim() - 1)))
        return x * (x.abs() >= thresh)         # Máscara binaria

# Modo de uso en modelo:
# h = self.tok_emb(x)
# h = HSAQ(sparsity=0.3)(h)    ← 30% de activaciones → 0
# h = transformer(h)           ← gradiente solo fluye por neuronas activas

6. HSAQ vs TurboQuant (Google)

Aspecto TurboQuant (Google) HSAQ
Enfoque Cuantización fija post-entrenamiento Sparsity adaptativa dinámica
Granularidad Por tensor (pesos) Por elemento (activaciones)
Umbral Fijo (calibrado offline) Dinámico (kthvalue por batch)
Hardware Requiere soporte INT8 CPU/GPU/TPU (solo kthvalue)
Calibración Dataset de calibración offline Zero overhead (inline)
Adaptabilidad Ninguna (mismo esquema siempre) Por batch (cambia con cada input)
Permite modelos más grandes No (solo comprime) Sí (sparsity = menos recursos)

Por qué HSAQ supera a TurboQuant

  1. No malgasta recursos: solo las neuronas relevantes se activan por batch
  2. Modelos más grandes en hardware limitado: con sparsity=0.3, un modelo 190M corre como si fuera ~133M, permitiendo ejecutar modelos que no cabrían de otra forma
  3. Adaptativo: el umbral se ajusta a la entrada, no hay configuración fija
  4. Sin calibración: no necesita datasets externos ni pasos post-entrenamiento
  5. Más eficiente energéticamente: menos FLOPs = menos consumo

7. Referencia rápida

Concepto Respuesta
¿Qué cuantiza? Activaciones (no pesos)
¿Cómo? Máscara binaria vía kthvalue
¿Cada cuánto se recalcula? Cada batch (umbral dinámico)
¿Qué reemplaza? AdamW como optimizer
¿Qué optimizer usa? SGD Nesterov (momentum=0.9)
Parámetros Solo sparsity (default 0.3)
¿INT8? NO
¿bitsandbytes? NO
¿BPE? NO