Skip to main content

MZTrain — Motor de Entrenamiento en Espacio Comprimido v1.3

Entrena modelos que no caben densos en tu GPU, mediante factorización SVD entrenable, rango progresivo/bidireccional (ElasticRank) y gobernador de VRAM — con su costo de calidad medido, preregistrado y publicado en este mismo repo.

License: MIT Authorship Prior Art Sealed Python 3.8+ PyTorch 2.0+ Tests Evidencia


La verdad en tres líneas (léela antes de nada)

  1. Si tu modelo CABE denso en tu GPU: entrena denso. A igualdad de parámetros, un denso más pequeño gana al factorizado en calidad (~10% de BPC) y a menudo también en VRAM y velocidad. Medido a 3 escalas, robusto a LR, schedule de rango y ubicación de la factorización (T4, T6).
  2. Si NO cabe: MZTrain es la puerta. El ahorro de memoria es real y crece con la escala (pesos+gradientes+Adam ∝ params); medido: un equivalente denso de 1.06B params entrena a 6 361 tok/s con 7.2 GB de pico en una RTX 4060 (bf16, batch 8).
  3. El framework es matemáticamente correcto y estable: el forward factorizado iguala la SVD ideal a 4 cifras sobre un modelo real de 97 capas, y la serie empírica completa corrió sin un solo NaN. Auditado (peritaje + peritaje matemático + criba), reparado y sellado.

Licencia y avisos

MZTrain es software libre bajo licencia MIT (ver LICENSE): puedes usarlo, modificarlo, redistribuirlo e incorporarlo en proyectos comerciales, conservando el aviso de copyright y el texto de la licencia.

Documento Qué contiene
LICENSE Licencia MIT.
AUTHORSHIP.md Declaración de autoría y co-titularidad.
NOTICE.md Atribuciones, terceros y marcas.
PRIOR_ART.md Publicación defensiva de las invenciones (prior art).
CONTRIBUTING.md + CLA.md Cómo contribuir (inbound = outbound, DCO).
TRADEMARK.md Política de marcas.
SECURITY.md Política de seguridad y divulgación responsable.
SEAL.json + MANIFEST.sha256 Sello de integridad (SHA-256 + SHA-512 + Merkle + firma Ed25519).

El objeto canónico de verificación es el repositorio git (o cualquier clon — los bytes viajan exactos gracias a .gitattributes):

git clone https://github.com/esraderey/Mztrain.git && cd Mztrain && python scripts/seal.py verify

Debe reportar OK con firma Ed25519 válida. Nota honesta: el sdist de PyPI empaqueta un subconjunto de instalación (sin .github/, bench/, JSONs crudos de evidencia…); verify dentro del sdist reportará faltantes — no es manipulación; verifica contra el repo.

Principio fundamental

En vez de entrenar tensores completos W (m × n), MZTrain entrena sus factores U (m × r), S (r), V (r × n) con r << min(m, n) — como parámetros de primer orden, no como compresión a posteriori. Los gradientes y los estados de Adam viven en el espacio factorizado: la memoria de entrenamiento entera se encoge con r.

Qué está medido (serie empírica T0–T22, preregistrada)

Todos los experimentos de esta sección tienen preregistro previo a los datos (hipótesis, métrica y condición de falsación fijadas antes de correr), artefactos JSON crudos y veredicto formal, en docs/evidencia/. Hardware: RTX 4060 (8.6 GB), Windows 11, torch 2.11+cu128.

Calidad a iso-parámetro con la línea base sana (T20–T22, 2026-10)

Pregunta Resultado (BPC de validación; 18 000 pasos y 3 semillas salvo indicación) Dato
E1: con una línea base sana, ¿gana F a Ds? No: F★ pierde en 3/3, hueco +0,051 (el +0,086 anterior era de otro corpus y programación); el sumidero de norma no aparece T20
E5: ¿importa la forma (d, r) a iso-parámetro? Sí pero poco (6000 pasos, 1 semilla): subir r/d mejora a F de forma monótona y se satura (F448 −0,024); el denso con la forma de F pierde con el estrecho T21
E9: ¿un optimizador espectral cierra el hueco? No: la receta con Spectron da −0,063 a F y Muon −0,066 a Ds; el hueco queda en +0,054. Fspec queda por debajo del denso AdamW en 3/3 T22

Memoria y capacidad (T0, T5)

Config Estado Dato
Pythia-410M fine-tune denso al límite 8.3 GB
Pythia-410M-equiv factorizado (engine completo) holgado 2.2 GB (3.9×)
Techo práctico denso (fp32, batch 8) ~280M 5.9 GB, 3 452 tok/s
Techo práctico factorizado (fp32) ~570M-equiv 6.0 GB, 5 333 tok/s
Hallazgo Windows/WDDM: no hay OOM — hay un acantilado silencioso ~7 GB donde la paginación a RAM colapsa el throughput ~30×. Diseña para quedarte debajo. t5_capacity.json

Velocidad con bf16 (T6) — el acantilado se mueve

Config (autocast bf16, batch 8) tok/s VRAM pico
Denso 277M-equiv 7 780 5.7 GB
Factorizado 850M-equiv 6 303 6.0 GB
Factorizado 1.06B-equiv 6 361 7.2 GB

Con fp32 ese 1.06B-equiv rendía 159 tok/s (zona muerta). bf16 reduce activaciones → el pico cae bajo el acantilado → 40×. 1B de tokens ≈ 1.8 días en una 4060. Paridad de calidad bf16 verificada en denso (dos escalas) y factorizado pequeño; pendiente en factorizado grande (ver Limitaciones).

El peaje de calidad (T4, T6, T7) — léelo antes de reivindicar nada

  • Gap iso-parámetro (factorizado vs denso de iguales params, mismo presupuesto): ~10% de BPC, estable de 11M a 152M (H1 "se cierra con la escala" falsada por regla preregistrada).
  • El gap no es un artefacto: tunear el LR lo ensancha (el denso aprovecha LRs altos mejor), el annealing de rango (192→64 con cirugía completa) no aporta nada detectable, y factorizar solo el FFN conserva el 85% del gap. Es el costo de capacidad del cuello de rango.
  • La dinámica fue interrogada (T7): sin muerte de direcciones (rango efectivo ≈ nominal), deriva de gauge real pero benigna, y el weight decay estabiliza al factorizado (nunca lo pongas en 0).

Compresión de un modelo YA entrenado: usa bits, no rango

Sobre Pythia-410M real: la truncación SVD matemáticamente óptima conservando el 50% de los params destruye el modelo (PPL ×~8 000), mientras que la cuantización calibrada (GPTQ INT4 de MNEME) cuesta +35% de PPL con 4× menos memoria. Entrena por rango, despliega por bits. Para factorizar un preentrenado con fines de análisis usa factorize_existing_model(preserve_map=True) — la variante fiel a la SVD (verificada a 4 cifras); el default con EPSI es para inicializar desde cero, no para transferir.

ElasticShape (nuevo en 1.3): entrena chico, crece a mitad de camino

La medición que abrió la puerta: a presupuesto corto, un denso pequeño aprende más calidad por segundo que cualquier modelo grande (T4/T6). ElasticShape lo convierte en mecanismo: entrena un denso pequeño, conviértelo EXACTO a factorizado (SVD completa), ensancha/profundiza con cirugía que preserva la función, y sigue entrenando grande — con la migración completa del estado Adam, corrección de escala de atención y compensación de varianza de LayerNorm.

Resultado T8 (preregistrado, veredicto): el morph alcanza la calidad del from-scratch en el 54% del reloj (3/3 seeds, ±0.4 s) y, a tiempo igual, rinde 2.34-2.37 BPC vs 2.90 del from-scratch. Deriva de la cirugía sobre modelos entrenados: 0.24-1.4%.

T9-T12 (2026-08-22) cierran las banderas que T8 dejó abiertas, todas con preregistro y umbral de muerte previos a los datos:

Experimento Pregunta Resultado
T9-A ¿a escala mayor? endpoint 38.8M (5.1× T8) → ratio 0.476 (3/3). El claim mejora con la escala
T9-B ¿cirugías encadenadas? 192→288→384 da 0.496 frente a 0.574 del salto único: encadenar es mejor
T9-C ¿en bf16? ratio 0.689, paridad de calidad (ΔQ 0.0195), speedup 1.42×, 0 NaN
T10 ¿con la tasa de aprendizaje afinada? sobrevive; y aparece que el factorizado desde cero sin rampa de LR falla 4 de 6 veces
T11 ¿qué protege: la fase densa o la rampa? 2×2: ambas bastan por separado. Corrige a T10 y fija el número honesto en 0.542
T12 ¿estaba la línea base mal equipada? a 3e-4 la rampa empeora la referencia: el 0.574 de T9-B no necesitaba corrección

Alcance honesto: char-WikiText-2, dos escalas (7.6M y 38.8M), tasas 3e-4 y 1.2e-3, fp32 salvo T9-C, 3-6 semillas por celda. El RFC recoge el fundamento matemático, los diez defectos que encontraron las auditorías ciegas y las amenazas a la validez.

Dos correcciones que la propia serie se hizo, y que conviene leer antes de reutilizar los números: (1) la varianza a semilla fija (~0.4 BPC) supera a la varianza entre semillas que el arco asumía (σ₁=0.068) — la tarea es bimodal; (2) las comparaciones de «BPC final» entre configuraciones que no han convergido miden quién va delante en un corte, no calidad alcanzable (T14). El banco incluye una guarda que lo impide (docs/evidencia/banco-t9-t14/convergencia.py).

from mztrain import GrowthEvent, LrWarmup, apply_event
from mztrain.elastic_shape import GPT, dense_lin

model = GPT(vocab, seq, d=192, layers=6, heads=6, lin=dense_lin)
# ... entrenar pequeño ...
ev = GrowthEvent(step=2000, factorize=True, new_d=384)
opt, reporte = apply_event(model, opt, ev, probe_x=probe)  # cirugia completa
if reporte["accepted"]:
    warmup = LrWarmup(opt, steps=200)                      # y a seguir entrenando

La revision en desarrollo incorpora rollback de cirugia, migracion de grupos/opciones AdamW (incluido AMSGrad) y ruido calibrado por norma funcional. Para activar una guarda de calidad, pasa probe_targets, max_loss_increase (nats/token) y/o max_kl (nats/token). Si se excede un limite, devuelve el optimizer original con accepted=False; no iniciar warmup en ese caso. Los limites se eligen antes del evento sobre sondas representativas. Sin limites, probe_x sigue siendo diagnostico. Ver contrato, ejemplo y limites.

Compatibilidad experimental: noise_scale ahora calibra la norma del mapa lineal agregado, no std(U). Las curvas con ruido pueden cambiar; los numeros T8-T14 anteriores corresponden a la implementacion 1.3.2 original y no validan aun esta revision.

Primitivas de bajo nivel en mztrain.shape_ops (ensanchar capas/embeddings/LN con mapas de índices, denso→factorizado exacto, bloques identidad, pad de estado Adam). Diseño y matemática de preservación: docs/SPEC-elasticshape-v1.md.

Cuándo usar MZTrain (y cuándo no)

Tu caso Recomendación
El modelo cabe denso en tu GPU Denso (mejor calidad por parámetro; con bf16 además rápido)
El modelo NO cabe denso MZTrain factorizado — asumiendo el ~10% de peaje medido
Comprimir un checkpoint entrenado Cuantización (MNEME/GPTQ), no factorización
Investigación de rank scheduling ZTrainEngine + ElasticRank (maquinaria auditada)

Ahorro de memoria (por construcción; el total emerge con la escala)

Componente Tradicional MZTrain Ahorro
Pesos 100% 20-30% 70-80%
Gradientes 100% 20-30% 70-80%
Optimizer (Adam m, v) 100% 20-30% 70-80%
Activaciones* 100% 40-100% 0-60%

* La factorización no reduce activaciones (conserva el ancho); el ahorro de esa fila proviene de ZActivationCheckpoint (INT8/MNEME), opcional e independiente. Por eso el ahorro TOTAL depende de la escala: nulo bajo ~50M (dominan activaciones), 3.9× medido a 410M, y creciente de ahí en adelante.

Limitaciones conocidas y configuraciones a evitar

  • No esperes ganar a un denso iso-parámetro en calidad. Está falsado a 3 escalas con preregistro. El valor del framework es habilitación, no eficiencia por parámetro.
  • RANDOM_K + error-feedback: NO usar (diverge geométricamente; hallazgo del peritaje matemático, sin reparar). Métodos seguros: TOP_K, ONE_BIT, INT8, SVD.
  • ZGaLoreOptimizer: NO usar (la cuantización INT8 lineal colapsa v→0; sin reparar).
  • Params en fp16 puro con optimizer comprimido: NO (underflow del log-quant). Usa fp32 + autocast (bf16), el patrón validado.
  • bf16 + factorizado GRANDE: valida con seeds antes de confiar. Un run a 57M mostró +0.44 BPC vs fp32 (1 seed, sin resolver); en denso y factorizado pequeño la paridad bf16 está verificada.
  • fp8: experimental. El path corre en SM89 pero multiplica S en bf16 (pendiente de arreglo) y forward_context usa fp16 en su rama fp8. No validado end-to-end.
  • weight_decay nunca en 0 con capas factorizadas (triplica el ruido entre seeds y empeora la media; T7).
  • Línea base sana, por defecto en el engine y en GPT desde 1.5.0 (T20): embeddings N(0, 0,02²) (GPT(emb_std=0.02)), AdamW con β₂ 0,95, eps 1e-8 y weight decay 0,01, recorte global a 1,0, rampa de 200 pasos y coseno a 0 (lr_schedule="warmup_cosine", un calendario por llamada a train()). Medido: el BPC inicial a d=768 baja de ≈ 720 a ≈ 10,4, y bajo esta receta el sumidero de norma del arco T4–T19 no aparece (rms del flujo final 9–10 frente a 273–356). Para reproducir 1.4.0: GPT(..., emb_std=None) y ZTrainConfig(weight_decay=1e-4, betas=(0.9, 0.999), lr_schedule="none"). Cambios de comportamiento, en el CHANGELOG.
  • El hueco a iso-parámetro no se cierra con lo probado (T20–T22): bajo la línea base sana el factorizado queda +0,051 BPC por detrás del denso estrecho (E1; el +0,086 anterior era de otro corpus y otra programación, no comparable pieza a pieza); subir r/d por la hipérbola o usar un denso con la forma de F no lo cierra (E5); un optimizador espectral mejora 0,065 BPC a los dos brazos por igual y lo deja en +0,054 (E9). A 13,5M y 18 000 pasos el denso estrecho gana bajo los dos optimizadores.
  • ElasticShape con la línea base sana: las bandas de deriva de widen de la SPEC (≤ 7 % en el toy) se midieron con emb_std=None; con 0,02 la deriva en el init es 0,04–0,13. Mira la deriva que reporta apply_event en tu modelo antes de fiarte de esa cota.
  • Reporta ≥3 seeds en cualquier comparación con factorizado: es la condición más ruidosa entre seeds (~×10 vs denso; causa abierta, sospecha de paisaje de pérdida).
  • El sello detecta manipulación del árbol sellado; binarios y rutas excluidas quedan fuera (ver scripts/seal.py).

Instalación

pip install mztrain            # desde PyPI
pip install "mztrain[mneme]"   # + MNEME (paquete PyPI `mnemosys`, import `mneme`)
git clone https://github.com/esraderey/Mztrain.git
cd Mztrain
python scripts/seal.py verify  # verifica integridad criptografica
pip install -e .

MNEME / MNEMOSYS (backend opcional de almacenamiento y cuantización)

MNEME se distribuye en PyPI como mnemosys (mismos autores; el paquete conserva el import histórico import mneme). Con pip install "mztrain[mneme]" MZTrain lo detecta y habilita:

  • Compresión post-entrenamiento (compress_model, GPTQ INT4) y almacenamiento seguro (SecureStorageBackend) en ZCodeBERT y en los ejemplos.
  • Store de activaciones ZSpace para ZActivationCheckpoint, opt-in con ZTrainConfig(mneme_activation_store=True). Medido con mnemosys 1.0.1: fidelidad INT8 (error relativo ~6e-3, MZTrain fuerza quantization_type="int8" porque el enrutado automático descompone tensorialmente las activaciones grandes) y un coste de ~0.2-0.6 s por activación porque persiste cada tensor en disco (directorio temporal propio, sin cifrado en reposo). Por eso el valor por defecto sigue siendo el INT8 interno (milisegundos). MZTrain exige al backend evicción por clave (delete/remove) y hace una sonda de fidelidad en el primer uso; si algo falla, avisa y cae al INT8 interno en vez de fugar memoria. Fuera de ZTrainEngine (p. ej. ZCodeBERT con z_checkpoint), el opt-in se activa con ZActivationCheckpoint.prefer_zspace = True.

Sin mnemosys, MZTrain usa su fallback INT8 integrado (acotado y verificado). El repositorio de MNEME es la otra mitad del pipeline: MZTrain entrena por rango, MNEME comprime por bits.

Inicio rápido

1. Entrenamiento completo con ZTrainEngine

from mztrain import ZTrainEngine, ZTrainConfig, RankSchedule
import torch.nn.functional as F

config = ZTrainConfig(
    initial_rank=32,
    max_rank=256,
    rank_schedule=RankSchedule.EXPONENTIAL,
    compress_optimizer_states=True,
    use_amp=True,                      # bf16 en hardware Ampere+
)
engine = ZTrainEngine(model, config)

def loss_fn(model, batch):
    x, y = batch
    return F.cross_entropy(model(x), y)

summary = engine.train(train_loader=train_loader, val_loader=val_loader,
                       loss_fn=loss_fn, epochs=50)

2. ElasticRank + Loss-Guard + VRAM Governor (opt-in)

config = ZTrainConfig(
    initial_rank=32, max_rank=256, rank_schedule=RankSchedule.COSINE,
    use_elastic_rank=True,
    elastic_rank_use_redundancy_signal=True,
    elastic_rank_loss_guard_enabled=True,
    use_vram_governor=True,
    compress_optimizer_states=True,
    use_amp=True,
)

3. Factorizar un modelo existente (análisis / punto de partida)

from mztrain import factorize_existing_model
z_model, stats = factorize_existing_model(model, rank=32, preserve_map=True)

4. Exportar para deployment

full_model = engine.export_full_model()
torch.save(full_model.state_dict(), "model_final.pt")
# despliegue comprimido: cuantiza con MNEME/GPTQ (bits), no truncando rango

Componentes

Módulo Qué hace Estado de auditoría
ZFactorizedLinear / Attention / TransformerBlock forward factorizado ((x·Vᵀ)·S)·Uᵀ Exacto vs SVD ideal (4 cifras, modelo real)
ZCompressedAdam Adam con estados INT8 (log-quant en v) Verificado = AdamW canónico; seguro en bf16
ZGradientCompressor TOP_K / 1-bit / INT8 / SVD + error feedback topology-aware Contractivos verificados (evitar RANDOM_K)
ZRankScheduler 5 políticas de crecimiento Correctas (solo crecen; no hay schedules descendentes)
ElasticRank v1-v3 rango bidireccional, sleep bank, loss-guard Cirugía auditada; S siempre fp32 en el bank
VRAM Governor presión EMA, histéresis, oom_guarded en el train loop GPU-validado
ZActivationCheckpoint activaciones INT8/MNEME Evicción simétrica verificada
scripts/seal.py sello sha256+sha512+Merkle + firma Ed25519 obligatoria con lista de confianza Endurecido tras peritaje
shape_ops + elastic_shape ElasticShape: crecimiento reversible, guardas de calidad y estado AdamW T8-T12 y doble G4 corresponden a v1 original; revision de seguridad pendiente de revalidacion empirica

Honestidad técnica sobre ElasticRank: rinde donde existe redundancia explotable. En pretraining desde cero los proxies no predicen el impacto real (Spearman ≈ 0.13) y queda deliberadamente inerte con loss-guard. El annealing descendente de rango (nacer alto → comprimir durante el entrenamiento) fue probado con cirugía completa y no aporta beneficio detectable (T6); las direcciones aprendidas a rango alto no caben en rango bajo.

Innovaciones reivindicadas (prior art)

Contribuciones originales de MSC Star Team publicadas en PRIOR_ART.md: entrenamiento directo en espacio factorizado SVD; scheduler de rango progresivo; ZCompressedAdam INT8; ZGradientCompressor con error feedback topology-aware; ZActivationCheckpoint MNEME/INT8; ElasticRank v1 (sleep/revive/prune con señal AND), v2 (redundancia por leverage del Gram), v3 (loss-guard como árbitro); probe de sensibilidad de pérdida; VRAM Governor con recuperación de OOM; reset coordinado tras refactorización. Fechas y detalle en el documento.

Desarrollo

pytest tests/ -v --no-cov          # 347 tests
ruff check src/mztrain/
python scripts/seal.py verify

El gate de cobertura --cov-fail-under=85 está pre-existentemente por debajo (79.7%); juzgar regresiones por conteo de tests con --no-cov.

Hoja de ruta (no implementado, propiedad reservada)

Descritas en PRIOR_ART.md como publicación defensiva; no son reivindicación funcional:

  • fp8 sobre factores ("la factorización como acondicionador numérico": U,V casi-ortonormales → aptos para fp8; S fp32). Hipótesis falsable, hardware SM89 listo.
  • ElasticShape a escala — el claim T8 (54% del reloj) está probado a 11M-equiv; extenderlo a 57M+ (T9), growths encadenados y bf16 es la continuación natural de lo ya publicado en 1.3.
  • Governor anti-acantilado WDDM — mantener el pico bajo el umbral de paginación silenciosa de Windows (medido: vale 10-40× de throughput).
  • Soporte distribuido (DDP/FSDP), kernel CUDA del forward factorizado, auto-tuning de rango, extensión de ElasticRank a capas sparse.

Contribuir

Bajo la misma licencia MIT (inbound = outbound); ver CONTRIBUTING.md y CLA.md.

Autoría

  • Esraderey — co-titular, arquitecto principal y co-inventor.
  • Raúl Cruz Acosta — co-titular y co-inventor.

Relacionados


© 2025-2026 MSC Star Team. Distribuido bajo licencia MIT. Integridad verificable con python scripts/seal.py verify.

Metadata

Release files for mztrain 1.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mztrain 1.5.0
File Size Uploaded
mztrain-1.5.0.tar.gz 460.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mztrain 1.5.0
File Interpreter ABI Platform
mztrain-1.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 610.0 kB

Release files / mztrain-1.5.0.tar.gz

Download URL mztrain-1.5.0.tar.gz
Size 460.1 kB
Tags Source
SHA-256 checksum
How to use checksums
f70b155c56306ca7103114e4679dd5f43b9bcb81dab9c024fc8787d24b2437e9
BLAKE2b-256 checksum
How to use checksums
b7882873ec5a3ee7a5c5e6eef0fe2084d0eb22153997ad4539b14ab3b4fdaa89
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.2

Release files / mztrain-1.5.0-py3-none-any.whl

Download URL mztrain-1.5.0-py3-none-any.whl
Size 149.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
176686dad3a63a78b246d0c23bfecf82799c7753a084a8c8a911dddb58a9ae93
BLAKE2b-256 checksum
How to use checksums
db2a34d512f2b803f7ad54b9ad6fa5130992c940a5faa2881fbefa3cd73e1873
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.2

Release history Release notifications | RSS feed

This release

1.5.0 This release

2 release files

1.4.0

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.3.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page