GPT Diffusion

Ternary-Bonsai-2-27B: cuantización ternaria real a 1.72 bits — un 27B en ~6 GB (con trampa: fork obligatorio de llama.cpp)

2026-09-26 · Devs #modelos#qwen#open-weights#benchmark#optimizacion

Ternary-Bonsai-2-27B: un 27B ternario en ~6 GB que no corre en tu llama.cpp de siempre

TL;DR

  • Cotejado verbatim contra el model card (26/09/2026): Ternary-Bonsai-2-27B es una recuantización ternaria de Qwen3.8-27B a 1.72 bits/peso. El pack GGUF PTQ1_0 ocupa 5.95 GB — el 11% de los ~54 GB del FP16 — con un segundo empaquetado (PQ2_0, 2.13 bpw, 7.21 GB) y una variante MLX de 7.67 GB (2.25 bpw por el contenedor).
  • Todo lo demás es vendor-reported: el “98.2% de la inteligencia FP16 retenida” (media 84.78 en 14 benchmarks en thinking mode), los ~47 tok/s en un M5 Max y la comparativa contra UD-Q4_K_XL e IQ2_XXS. La eval es de PrismML (EvalScope + vLLM en H100); no existe reproducción independiente a fecha de hoy.
  • La trampa principal: los ficheros NO funcionan en llama.cpp stock. Rechaza PTQ1_0/PQ2_0 como tipos desconocidos y, peor, carga la variante Q2_0 sin ningún warning y produce basura. Necesitas el fork PrismML-Eng/llama.cpp; en Apple Silicon, MLX con el loader que trae el propio pack — los loaders MLX ordinarios devuelven salida incorrecta en vez de un error.
  • La trampa fina: los ~47 tok/s del titular salen de una tabla medida sobre un build anterior a la rotación Hadamard, marcada “pending re-measurement”. En el stack actual, lo medido en Apple es un M5 Pro a 28.1 tok/s.
  • Adopción, no calidad: 3.247.527 descargas acumuladas y 2.128 likes en Hugging Face (API consultada el 26/09/2026). Que la gente descargue a saco no es un benchmark.

Contexto: qué es Bonsai 2 exactamente

Qwen publicó Qwen3.8-27B en agosto — aquí está nuestro análisis y aquí la destilación de 700 usuarios reales. Es un denso de 27B, multimodal, con 262K de contexto y Apache 2.0, con el problema clásico de los modelos densos: en FP16 ocupa unos 54 GB, y en casa te toca cuantizar.

PrismML ataca ese problema por la vía de la cuantización ternaria: en lugar de bajar cada peso a 4 u 2 bits con escalas, reduce el alfabeto de cada peso a {-1, 0, +1}, con una escala FP16 compartida por grupo de 128 pesos. Bonsai 2 aplica ese formato a Qwen3.8-27B entero: embeddings, proyecciones de atención, MLP y LM head. El card reivindica que no hay “high-precision escape hatches” detrás de la etiqueta low-bit: solo 26.2M parámetros — el 0.0976% del modelo de lenguaje, el estado recurrente de las capas de atención lineal más las normalizaciones — viven por encima del ternario.

No es la primera iteración: la edición anterior de Bonsai 27B promedió 80.98 en esta misma suite (recomputada like-for-like, según el card); esta sube a 84.78. Y según la API de Hugging Face (26/09/2026) acumula 3.25M de descargas y 14 Spaces. Las métricas se mueven rápido: esa misma mañana la señal de research anotaba 2.82M de descargas. La curiosidad corre más que las réplicas independientes.

Los números del vendor, con fecha

Fuente: model card GGUF, consultado el 26/09/2026. Eval en thinking mode, media de 14 benchmarks, misma infraestructura para todas las variantes (según PrismML):

Variantebits/peso realesTamañoMediavs FP16
Qwen3.8-27B FP1616.0~54 GB86.32100%
UD-Q4_K_XL (“4-bit”)5.217.6 GB85.1898.7%
IQ2_XXS (“2-bit”)2.167.27 GB72.5984.1%
Bonsai 2 27B (ternario)1.725.95 GB84.7898.2%

Leído en frío: Bonsai 2 se queda a 1.54 puntos de la media FP16 ocupando el 11% del espacio, supera en más de 12 puntos al IQ2_XXS siendo además más pequeño (el 82% de su footprint) y el “4-bit” convencional solo le saca 0.4 puntos con el triple de tamaño. Por categorías, el vendor afirma que matemáticas casi no se mueve (97.06 → 96.57), coding queda empatado (89.07 → 89.42) e instruction following incluso sube un pelín (81.25 → 82.66); la caída se concentra en knowledge/reasoning (85.55 → 79.86) y visión (71.36 → 66.19).

Si la tabla aguantara una auditoría externa, sería el mejor ratio calidad/GB publicado para este modelo. Si.

Por qué esa tabla todavía no es un hecho

  1. Es la evaluación del interesado. Mismo harness, mismo decoding, misma GPU y la referencia FP16 medida por ellos. Nadie de fuera ha replicado nada todavía.
  2. Los terceros ya citan cifras distintas. Marktechpost y WebAI News recogen “20 benchmarks” con media 83.9 — otra suite, no la del card. No las mezclamos: usamos solo la fuente primaria. La discrepancia es en sí la señal de que la eval es del vendor, sin auditoría aún.
  3. Las propias fichas del vendor no concuerdan entre sí. La ficha GGUF pone la fila IQ2_XXS a 2.16 bpw y 7.27 GB; la ficha MLX del mismo modelo describe el build “2-bit” de referencia como 2.8 bpw a 9.4 GB (“a widely-used 2-bit build… is really 2.8 bits/weight”). La fila de la competencia cambia según la ficha; la fila de Bonsai, curiosamente, nunca.
  4. “98.2% of FP16 intelligence retained” suena a métrica estándar y no lo es. Es la media de SU suite de 14 benchmarks. Útil como orden de magnitud, no como número de catálogo.

Cómo mete 27B en 6 GB: el formato ternario g128

Un peso ternario {-1, 0, +1} lleva log₂3 ≈ 1.585 bits de información. Con la escala FP16 amortizada entre 128 pesos, el formato g128 queda en ~1.71 bits/peso efectivos; sumando los tensores que viven por encima del ternario, el modelo entero queda en 1.72 — una reducción ideal de ~9.3x contra FP16.

La pieza que hace que esto funcione (y que luego provoca la trampa) es la rotación Hadamard: cada matriz se transforma por bloques de 1024 en una base ortogonal antes de asignar los valores ternarios, y el runtime debe aplicar la transformación correspondiente a las activaciones en caliente. La rotación va plegada offline en los pesos y el fichero la declara como metadato: el runtime la aplica o rechaza el fichero. Sin esos kernels de activación, un “2-bit” que cargue no es un modelo degradado — es ruido con forma de modelo.

Los dos empaquetados GGUF son la parte práctica: PTQ1_0 empaca los trits densamente (1.75 bpw, 5.95 GB) y PQ2_0 mete cada trit en un slot de 2 bits (2.13 bpw, 7.21 GB). Los pesos se consumen empaquetados, sin expandir nunca a FP16. Y no hay un ganador universal, según su propia tabla de throughput: PTQ1_0 gana en decode en las GPUs Ada y la L4 (donde manda el ancho de banda de memoria), PQ2_0 gana en H100, A100 y las Blackwell, y gana el prompt processing en todas partes. El contenedor MLX, por su parte, guarda escala y sesgo por grupo (2.25 bpw, 7.67 GB de LM) y además incluye la vision tower en FP16 sin cuantizar — 8.60 GB en disco el pack completo; en GGUF la visión va aparte como un mmproj Q8_0 de 0.63 GB que solo cargas si sirves imágenes.

La trampa principal: necesitas SU llama.cpp

Lo dice el card, verbatim: stock llama.cpp “rejects PQ2_0 and PTQ1_0 as unknown types, and it loads Q2_0 without any warning and produces garbage”, porque no tiene runtime de activaciones Hadamard. Es decir: o el fichero no carga, o carga y te devuelve salida inservible sin un solo error en el log. Para una pieza cuyo argumento de venta es el tamaño, no poder confiar en el runtime estándar es el coste oculto de la operación.

Qué hay que usar en realidad:

  • CUDA/Metal/CPU: el fork PrismML-Eng/llama.cpp (rama prism), con binarios precompilados por plataforma. Existe y está documentado; el propio card deriva toda la operativa a su repo Bonsai-demo, que llevan como “source of truth” con binarios pineados.
  • Por extensión — inferencia nuestra, no del card: todo lo que se apoya en llama.cpp stock (Ollama, LM Studio y similares) está fuera de juego con estos ficheros mientras no integren estos kernels. No hay ollama run que valga.
  • Apple Silicon: el pack Ternary-Bonsai-2-27B-mlx-2bit declara model_type: prism_hadamard_qwen35 y exige el loader incluido en su directorio runtime/. El card lo confiesa sin rodeos: los loaders MLX ordinarios se saltan la transformación de activaciones y devuelven “wrong output rather than an error”. La misma filosofía que en GGUF: falla en silencio.

Trampas finas que el titular no cuenta

  • Los ~47 tok/s del titular vienen de un build anterior. La tabla “Additional Apple Platforms” (M5 Max 47.0 / M5 Pro 28.7 / M4 Pro 18.0 tok/s) está medida sobre el build pre-rotación y marcada “pending re-measurement” en el stack actual. Lo único medido en el stack vigente en Apple es un M5 Pro: 28.1 tok/s de decode (PQ2_0) y 387 tok/s de prefill. Sobre un M4 Pro, el card reconoce que con prompts largos el límite es el prefill (~125 tok/s), no el decode.
  • El modo low no existe. El card: low reasoning effort “is not supported and when selected the model will behave close to xhigh”. Crees que has pedido el modo corto y sigue gastando como el modo largo.
  • Piensa por defecto, y mucho. El template arranca en xhigh; con un límite tipo -n 256 cortas la generación en plena reflexión, antes de cualquier respuesta. Si quieres equilibrio, hay que pedir medium explícitamente.
  • Dos contenedores, dos verdades sobre el tamaño. El “~6 GB” es el LM en PTQ1_0. Con visión en MLX son 8.60 GB; el downgrade del formato MLX (2.25 frente a 1.75 bpw) es propiedad del contenedor, no de la representación — mismos pesos ternarios, verificables bit a bit según el card.

Cuándo lo usaría y cuándo no

Dónde sí. Portátil Apple Silicon con 16-24 GB unificados: es hoy el caso más interesante — un 27B con razonamiento que cabe entero en memoria y deja sitio a contexto (262K heredados del backbone híbrido, ~75% atención lineal, que según el vendor es lo que lo hace práctico on-device). Expectativa honesta: ~28 tok/s en un M5 Pro, no los 47 del titular. En GPU, cualquier tarjeta de 24 GB lo respira: la tabla del vendor da ~130 tok/s en una RTX 5090 y ~30 en una L4 de 72 W. Y el caso clásico del local: privacidad por construcción y uso offline.

Dónde no. Si tu carga vive en visión fina (MMMU-Pro cae de 81.73 a 75.49, OCR Bench v2 de 60.99 a 56.88 — la categoría que más sufre junto a knowledge/reasoning), si necesitas el ecosistema estándar sin compilar forks ajenos, o si buscas máxima calidad sin condiciones: el UD-Q4_K_XL sigue ahí, a 0.4 puntos por el triple de tamaño y sin salir del toolchain de siempre.

Antes de casarte con él en algo serio, la prueba mínima que yo haría: benchmark propio sobre tu carga real contra el Q4 convencional en tu hardware. El detalle que más debería importar de la eval del vendor no es la media sino el patrón de fallo del convencional: IQ2_XXS se hunde en AIME26 (57.5) y LiveCodeBench (56.4) mientras mantiene un 88.93 en MMLU-Redux — por eso un test casual de 10 preguntas no detecta el colapso. BFCL v3, la referencia agéntica de la suite, cae poco (76.74 → 74.92); tu caso puede no ser ese, en ambos sentidos.

Fuentes

Cargando comentarios...