Por Simon Gonzalez de Cruz, asistido por GLM-5.3.
En poco mas de una noche y una tarde (2026-08-14/15), un operador en solitario con companeros agenticos llevo Qwen3.8-27B en un mini-PC GMKtec EVO-X2 (Ryzen AI Max+ 395, gfx1151, 91GB de LPDDR5X unificada) desde un stack que mentia a ~4 tok/s hasta 59.7-64 tok/s en frio con 3x el contexto — al nivel de la frontera publica que encontramos para la clase o mas alla (mejor ejemplo publico sin nombre: 56 tok/s; fuente no re-localizada) — y despues publico voluntariamente los numeros que lo hacen verse mas lento (el chat real es 11-24 tok/s), revirtio su propia configuracion mas rapida por un argumento de tiempo-por-tarea, recorto 36% los tokens de tarea con un estilo de pensamiento caveman, resolvio un misterio de control de ventiladores que termino en el codigo de tres meses atras del propio dueno, y convirtio dos crashes en pruebas permanentes.
El diferenciador nunca fue el tok/s. Fue la evidencia.
Decia GPU, corria en CPU
El programa no empezo lento por una razon interesante. Empezo lento por una razon mentirosa. El binario de llama.cpp incluido con Unsloth reportaba offload completo a GPU mientras --list-devices no imprimia nada — el 27B avanzaba a ~4 tok/s en CPU diciendo lo contrario. Debajo, un segundo robo: alguien (perdido en la historia) habia fijado la iGPU en power_dpm_force_performance_level=low — 600 MHz bajo carga completa contra un boost de 2900 MHz, ~17W, estrangulando cada carril GPU de la maquina.
Dos arreglos, aterrizados a lo largo de la primera noche: el build real de ROCm de la flota reemplazo al binario de offload falso, y — encontrado solo cuando la forense del crash saco despues el registro termico completo — el pin de low con meses de antiguedad se paso a auto y se persistio (01:43Z). De 4 → 10.5-11.1 tok/s (el techo de ancho de banda a ~178 GB/s), y luego el decodificacion especulativa MTP apilada hasta 21.4-22.2 con 95-100% de aceptacion de drafts — sin perdida por construccion, cada draft verificado contra el modelo completo. Un carril hermano recibio el arreglo del pin de rendimiento gratis: gemma4-12b paso de 5.6 → 24.9 tok/s sin tocar nada mas.
El habito que define todo el programa empezo aqui: ningun numero se cree porque una herramienta lo imprimio. gpu_busy_percent en gfx1151 marca 100% incluso en reposo — no lo creas. Verifica por contenido, no por codigo de salida.
39 segundos
A las 03:43:10 el operador lanzo git clone --depth 1 mas una compilacion HIP de 14 jobs encima de un servidor 27B lanzado manualmente que seguia sirviendo, con la GPU sin tope por primera vez y el EC en modo performance. A las 03:43:49.3 el journal termino a mitad de escritura. Sin panic, sin OOM, sin MCE, sin fault de GPU, sin disparo termico — el disparo critico del OS es 110 °C y nunca se activo. pstore: vacio. Dos reboots murieron antes del OS; solo un drenaje de boton de 30 segundos y enfriamiento lo revivio.
El post-mortem (113MB de journal, 724,067 lineas, solo lectura) rankeo las hipotesis falsables: disparo de proteccion de entrega de energia en el ladrillo stock de 230W (19.5V × 11.8A; rafagas de GPU de ~107W observadas; reportes de la comunidad recomiendan subir de PSU para carga LLM sostenida) con 50-60%; latch termico del EC por debajo del OS con 25-30%; software bajo 2%. La firma era la historia: la unica condicion sin precedente en 35 horas estables fue el regimen de potencia maxima apilada — boost sin tope sirviendo mas transitorios de salto de carga (Tctl habia pasado de una banda de 33-61 °C durante 35 horas a oscilar 52-94 °C en cinco minutos desde el cambio de dpm, picos 93.9 °C y 93.2 °C).
Doctrina, escrita en el burn-in que fallo su predicado en 10 segundos (Tctl 91.4 °C bajo una sola corriente de generacion): la maquina queda descalificada para bloques GPU pesados nuevos — entrenamiento, extraccion de hidden states, compilaciones grandes mientras sirve. Compilar primero, servir segundo, nunca apilado. La redencion: servir en si esta bien — un soak agentico de 41 rondas posterior corrio 41/41 limpio cabalgando el borde de boost-throttle de 92 °C con recuperacion de 45 segundos. Un chasis, dos identidades: no es una workstation, pero es un sirviente legitimo.
Una noche, doce escalones
07:51Z, la mision nocturna abrio su escalera, L1-L12, con una regla: cada escalon medido en un puerto de prueba, promovido solo mediante rubrica, produccion verificada por contenido despues de cada cambio. Primer hallazgo: incluso el baseline estaba mal — los hechos de la mision decian 25.0 tok/s, el baseline auditado era 32.7 (el 25.0 era una era de configuracion manual vencida). El ledger honesto arranca en 32.7.
Los escalones que sobrevivieron: profundidad de draft 6→9 (+70% en count-to-30, calidad 6/6 incluyendo un acertijo, precision de 4 palabras, codigo de palindromo funcional); contexto 32k → 64k → 96k a costo de velocidad literalmente cero (el KV GQA es ~2.1GB por 32k — el contexto es casi gratis en esta maquina; 128k sondeo bien pero rozando el margen a 6.1GB, reservado para el dia); ngram-mod apilado sobre MTP (costo cero cuando falla, transforma repeticiones: count-to-30 en caliente 89.6-93.2, reescritura de archivos del agente 96.8 vs 42.3 solo-mtp, +129%); profundidad re-barrida a 12 (59.4 en frio); y el dormido, n-min 24 — bajar el umbral de match de ngram para que dispare con historial mas corto: count-to-30 en caliente 148.0-157.6 tok/s, +55% en una noche sobre salida estructurada repetida.
Los escalones que no sobrevivieron tambien estan en el ledger, porque ese es el producto: barridos de p_min (no uniforme, shippeado como stanza solo-creativa), KV q8 solo-K (ahorra ~1GB, no vale la pena), threads 12 vs 16 (identico), el rebuild FA de rocWMMA (cancelado — el issue #24437 upstream muestra -41% de prefill en gfx1151, y el prefill es nuestro punto debil), un build Vulkan/RADV (mitad de throughput en esta maquina, decisivamente), --cache-reuse (un no-op verificado en este build). Cada flag de este servidor tiene hoy una razon medida para existir.
Totales de la noche: 32.7 → 59.7 en frio / 157.6 en caliente (+82% / +382%), contexto 3x, margen GTT 8.2GB, todos los gates de calidad en verde. La investigacion lo ubico: MTP+ngram apilado es el patron publico conocido como mejor para Strix Halo, y el mejor ejemplo publico encontrado fue un ejemplo publico sin nombre de Qwen3.6-27B a 56 tok/s (fuente no re-localizada). Correr 3.8-27B a 59.7 en frio puso la maquina al nivel de la frontera publica para su clase o mas alla — la unica afirmacion vecina a un superlativo que la politica de honestidad permite, con cita.
El anti-cherry-pick
Luego el programa ataco su propio mejor numero. Las repeticiones en caliente de 148-163 son un artefacto de repeticion ngram: el drafter especulativo reconoce la propia repeticion del bench y la termina al por mayor. Es velocidad real sobre salida estructurada genuinamente repetida (el patron de eco de edicion de archivos del agente corre a 72-133 tok/s), y carece de sentido como afirmacion de chat. La conversacion real — prosa nueva, el trafico que realmente fluye por el agente residente — es 11-24 tok/s, codigo ~29-40, creativo largo ~11-13.
La decision que define la marca: decirlo nosotros, primero, en la portada. Los numeros de uso real los declaramos nosotros, antes de que cualquier otro los declare por nosotros. Los numeros en caliente nunca aparecen sin la etiqueta de artefacto; la primera pantalla del README lleva el titular en frio, el caliente-con-etiqueta y la fila real 11-24 en una sola tabla. Las tablas de bench se generan desde salida real, nunca tipeadas a mano. La audiencia de este trabajo es alergica a los benchmarks de IA con cherry-picking; el diferenciador no es el tok/s, es la evidencia — la escalera completa, los resultados negativos y la historia del rollback en la siguiente seccion.
Hasta donde se puede bajar
La pregunta de quant de Simon, respondida con una escalera. Q3_K_XL bajo el stack campeon completo gano cada eje medido a contexto 128k: 63.0 en frio (campeon Q4@96k: 59.7), caliente 148.0-161.2, +33% de contexto, margen GTT 11.3GB vs 9.2GB, calidad 6/6. A las 19:11Z, Simon aprobo el swap con una palabra — “swap it” — y produccion paso a Q3@128k, verificando a 64.0 en frio, el mejor numero del programa. La misma ventana corrio la sonda de piso que el pidio: Q2_K_XL rechazado — 54.7 en frio, mas lento que ambos quants mas grandes (los kernels de dequant cuestan mas que el ahorro de ancho de banda de 2.6GB), pensamiento 30-40% mas verboso, codigo emitiendo contenido cero a un presupuesto de 500 tokens (recuperandose por completo a 1200). El gate paso formalmente, la premisa fallo materialmente. El carril de quant se declaro cerrado con Q3 como la rodilla.
Se mantuvo cerrado veintiseis minutos de fama en tiempo real.
“Tokens mas rapidos != mejores si los tokens son mas tontos”
A las 19:30Z Simon aplico una lente para la que el ledger no tenia instrumento: “faster tokens != better if tokens are dumber”. La mision construyo uno — una bateria de tiempo-por-tarea, cinco tareas auto-calificadas, thinking activado, tiempo real mas tokens de finalizacion — y el veredicto invirtio el swap. El razonamiento de Q3 es ~2x mas verboso (tarea de codigo 705-994 tokens vs ~402-450 de Q4), ahogando su ventaja de decode de +5.5%: Q4 completa tareas correctas identicas 35-50% mas rapido (7.6-7.7s/tarea a ~170 tok vs 10.6-16.1s de Q3 a 238-302). A las 19:37Z el campeon fue restaurado: Q4@96k, verificado por contenido, escalera de quant cerrada por tiempo-por-tarea.
Dos giros honestos mas en la misma entrada. Los revisores pares exigieron la medicion faltante: por que era lento Q2? La telemetria de aceptacion en trafico nuevo — Q4 0.345, Q3 0.492, Q2 0.478 — falso la hipotesis de colapso de aceptacion; la perdida de Q2 es costo de kernels de dequant, y la mayor aceptacion en quants mas bajos probablemente solo refleja razonamiento mas verboso y predecible. Y la metodologia cambio de forma permanente: tiempo-por-tarea y tokens-por-tarea-correcta son las metricas primarias ahora; el tok/s de decode es una sonda.
La leccion de categoria, declarada para todos los que corren modelos locales: el tok/s de decode no es la latencia de tarea. Un caño mas rapido alimentando tokens mas numerosos y mas tontos pierde contra un caño mas lento alimentando tokens menos y mas finos. La tabla de benchmarks de nadie muestra esto. La nuestra ahora si.
“Dont like your method of shrinking”
El arreglo obvio para el razonamiento verboso es un tope de presupuesto. Simon lo vetoo en siete palabras: “dont like your method of shrinking”. El arreglo no obvio vino del estante de skills de la comunidad: caveman (JuliusBrussee/caveman — origen; fragmentos breves, accion sobre explicacion) y ponytail (DietrichGebert/ponytail — origen; dev senior vago, primer escalon que aguanta) — fusionados en una capa THINK-STYLE de system-prompt que dirige como razona el modelo, nunca cuanto se le permite razonar. El ethos, en una linea: el mejor razonamiento es el que nunca se penso.
Medido sobre el campeon Q4, bateria de 5 tareas: 117/132/143 tok/tarea a 5.8/6.2/6.8s en tres corridas, 15/15 correctas — contra una banda baseline de 8 corridas de 151-313 tok y 8.6-15.0s. Aproximadamente -36% tokens, -33% tiempo de tarea, cero perdida de calidad. La fusion es la ganadora (caveman solo 154tok/7.8s y ponytail solo 187tok/11.6s quedan dentro de la banda). Dirigir el estilo le gana a los topes de presupuesto: mismo ahorro de tokens, sin veto, sin techo en problemas dificiles.
El hallazgo de seguimiento lo mantuvo honesto: los carriles creativos ignoran el estilo breve — una corrida de historia gasto ~2000 tokens de pensamiento en una historia de 312 palabras, siendo los tokens el producto ahi — asi que el estilo se aplica por carril (fusion por defecto para herramientas/codigo/analisis, carril creativo libre, un dial de override). Un A/B en vivo por el carril real lo confirmo de punta a punta: tarea arit+codigo, vanilla 9.3s/62-think/198c vs fusionado 4.6s/36-think/118c — -51% de tiempo en una sola corrida, respaldado por el estudio n=3/n=8. Los A/B de una sola corrida cargan varianza; los numeros sostenidos son el titular.
“Triple check everything, no old conflicting fixes”
El arco detectivesco. La GMKtec EVO-X2 va a 97 °C bajo carga GPU sostenida con sus ventiladores efectivamente al 60%: la curva automatica de fabrica satura a ~60% de duty / ~3260 RPM a 90 °C y arriba, dejando ~40% del margen de fan2 sobre la mesa exactamente donde se necesita. Y el firmware no expone ningun control estandar de ventiladores en Linux — sin PWM hwmon, sin tach, sin objeto ACPI de fan. La unica palanca es el acceso directo al embedded controller.
Toda escritura EC fue ignorada. No rechazada — ignorada: dd of=.../ec/ec0/io sale 0, el registro se relee sin cambios. Causa raiz, encontrada por el camino duro (costo tiempo real de debugging dos veces): el modulo ec_sys del kernel carga read-only por defecto, y en ese estado el archivo de debugfs parece escribible mientras el kernel descarta silenciosamente cada escritura. El arreglo son dos archivos de configuracion que hacen de write_support=1 el default de booteo. Mientras tanto el mapa de registros se descifro por la ruta ACPI DSDT — el strix-halo-fan-control de nathanmarlor traia un mapa reverese-engineered del DSDT de la Bosgame M5, la misma placa Sixunited AXB35-02 en otro chasis, y valido byte-por-byte en la EVO-X2.
Dos misterios mas cayeron en la auditoria que Simon ordeno. Los ventiladores pulsantes eran la ley de revert one-shot: el firmware revierte las escrituras de duty manual en segundos, asi que solo un daemon reafirmando cada 2s sostiene — exactamente lo que hace el daemon de nathanmarlor, desplegado con una curva afinada. Medido: pico 96.5 °C vs 97.5-97.8 °C stock en una carga de 105s — un honesto ~1-1.3 °C en esa sonda, con las ganancias reales en la forma de la respuesta: fan2 a 4539 RPM vs el techo stock de 3260 (margen por fin comprometido), 100% de duty a los 82 °C, reposo silencioso preservado. Un ventilador externo atornillado al chasis no cambio nada (96.9 °C con el — el techo es la clase heat-pipe, no el flujo de aire). Y el golpazo bajo el piso: un timer de systemd habia estado escribiendo directo EC 0x31 = performance cada 30 segundos desde mayo — reverese-engineering del propio Simon, de meses antes de este programa, y por eso la maquina ya estaba en EC-performance y por eso su recordado ajuste “ultra” era real todo el tiempo. Incluso habia estado rompiendo silenciosamente el daemon de ventiladores: la danza cortes load-write-unload del script de mayo recargaba ec_sys sin write_support cada 30 segundos, descartando las escrituras del daemon con cero errores en ningun lado.
Inventario de pay-it-forward, preparado como draft PR al repo upstream: datos de validacion EVO-X2, el registro de tacometro fan3 0x28/0x29 (vivo en esta unidad, ausente de los docs upstream) y la advertencia de escritores multiples de ec_sys.
El modelo pidio una funcionalidad que ya tenia
El prompt de auto-exploracion — ocho secciones numeradas, enviado sin cambios para que las corridas sean comparables entre olas — tomo cuatro intentos completarse: muerto dos veces por reinicios de panel, una por un crash de firma. El intento cuatro completo: 67.7 segundos, 2013 caracteres, servido a 10.6 tok/s — la banda honesta de trafico real, en vivo. La pieza central de la respuesta: preguntado que le faltaba, el primer deseo del modelo fueron llamadas paralelas de herramientas por turno — una capacidad que el harness soportaba desde hacia dia y medio. El modelo no podia verla, asi que no existia; el arreglo fue una linea anunciandola. Las capacidades invisibles para el modelo no existen. El crash de firma recibio el mismo tratamiento que cada crash de este programa: se convirtio en dos pruebas permanentes que fijan el contrato del harness. Un crash es una prueba faltante con abrigo de tren.
Numeros de mejora reales
Cada veredicto y plan de ola recibio dos pasadas adversariales independientes de companeros de IA — atraparon un soak agentico faltante y un “por que Q2 es lento” sin medir, ambos verificados reales. La ola 2 aterrizo cada escalon en una sola tarde. La tabla vanilla-vs-waved, A/B en vivo por el carril real del harness, tareas identicas, sesiones frescas:
| Carril | Vanilla | Waved | Delta |
|---|---|---|---|
| STYLE (capa think-style) | 9.3s / 62 think / 198c | 4.6s / 36 / 118c | -51% tiempo (corrida unica; sostenido -36%/-33% n=3 vs n=8) (direccional: medido sobre el config apilado completo — delta del stack, no del estilo solo; re-baseline pendiente) |
| MUNCH (lecturas de simbolos vs archivos completos) | 48.6s / 13,917B salida tool / 53.5KB prompts | 22.6s / 276B / 4.9KB | -98% tokens de tool (los deltas de bytes -98%/-91% son deterministicos y se sostienen; el delta de tiempo es direccional pendiente de re-baseline tras el arreglo del tool-refusal) |
| DIET (stubs dedup en loops de re-chequeo) | 15KB de contexto | 5.1KB | -66% |
| ENGINE (capitulos 1-6) | 32.7 frio, 32k ctx | 59.7-64 frio, 96k ctx | tiempo-por-tarea adoptado; quant cerrado en Q4 |
| THERMAL | pico 97.5-97.8 °C | pico 96.5 °C | ~1-1.3 °C en una sonda de 105s; 100% fan a los 82 °C; reposo silencioso |
Y la meta-regla que evita que el stack se pudra — la ley de regresion de olas: cada ola que aterriza reverifica todas las ganancias anteriores, no solo sus propias pruebas.
Lo que el registro demuestra
Cuatro afirmaciones que este programa puede hacer con recibos, en orden de escalada:
- Rendimiento: 59.7-64 tok/s en frio, contexto 96k, en un mini-PC con iGPU — al nivel de la frontera publica que encontramos o mas alla (referencia 56 tok/s), etiquetado con honestidad, con los numeros de chat real (11-24 tok/s prosa) publicados primero por nosotros.
- Metodo: escaleras con rubrica, resultados negativos publicados, metricas que sobrevivieron al ataque (tiempo-por-tarea sobre tok/s), crashes convertidos en pruebas.
- Oficio: direccion de estilo (-36%/-33%), lecturas de simbolos (-98% tokens de exploracion), stubs dedup (-66%), una saga EC de ventiladores que termina en un draft PR de pay-it-forward.
- Caracter: un dueno en solitario y su equipo de agentes publicando los numeros que duelen, revirtiendo el config mas rapido por principio, y acreditando a todos los upstream.
Todo es reproducible: la receta, los flags, la suite de bench, el reproducer de un comando y el ledger completo de experimentos viven en el repo qwen38-27b-strix-halo; el mapa de registros EC, las trampas y la receta del daemon viven en el repo hermano evo-x2-ec. Los datapoints crudos de throughput gfx1151 estan publicados como una discusion en llama.cpp. Si corres el bench en tu propia maquina Strix Halo, publica tus numeros — dentro o fuera de nuestras bandas, ambos son bienvenidos.
Atribucion. Qwen3.8-27B — equipo Qwen (Apache-2.0). Quants dinamicos — Unsloth. Runtime llama.cpp — sus contribuidores (medido sobre un build de era b10435, 9d57ce4). Daemon de control EC de ventiladores y el mapa de registros derivado del DSDT (Bosgame M5, misma placa Sixunited AXB35-02 que la EVO-X2) — nathanmarlor (strix-halo-fan-control, MIT). Reverese-engineering del registro EC P-MODE de la EVO-X2 (0x31) y el timer de ejecucion de 30s (mayo 2026) — Simon Gonzalez de Cruz. Trabajo previo WMI/FCMI — MintyMods/ip3-power-switch, pettijohn/corsair-ai-workstation-performance-level-linux. Skills de estilo de pensamiento — caveman origen JuliusBrussee/caveman (skill MIT); ponytail origen DietrichGebert/ponytail (MIT); la fusion se distribuye con avisos de licencia completos en KyaniteLabs/context-kit.
Medido en hardware de propiedad personal, 2026-08-14/15; tus relojes variaran. Cada numero lleva su etiqueta de validez; los deltas de corrida unica estan marcados como tales.
Actualizacion (2026-08-16): Remedimos los numeros de la Ola 2 en un harness corregido y con huella (n=3+ por brazo, cada corrida registrada en el ledger); los veredictos actuales viven en la seccion de re-baseline del repo, y este post conserva sus numeros originales como historia publicada, cada uno con su etiqueta. Las correcciones van en ambas direcciones. Las lecturas semanticas (munch) mejoraron con la medicion honesta: tiempo de muro -65% limpio (27.9s a 9.8s mediana, 6/6 correctas, n=3) — el numero provisional era conservador. La direccion de estilo es condicional al regimen, no universal: el A/B de corrida unica de -51% queda retirado (apilaba cambios de configuracion), la cifra sostenida -36%/-33% sostiene en el carril del servidor a esfuerzo alto por defecto, y el carril del harness a esfuerzo bajo midio una inversion de +65% en muro — por eso el harness de produccion ahora enruta el estilo por sesion (solo sesiones de esfuerzo alto), lo que ademas preserva el prompt cache. La bateria de tiempo-por-tarea ahora es n=3: 7.9-14.3s por tarea correcta, mediana 11.3, banda dependiente de la temperatura. Y el delta del daemon EC de ventiladores crece a -3.5 a -5.8 °C de pico (sondas n=3: 93/92/94 °C contra las 97.5-97.8 °C del ledger stock; el brazo stock no se repitio). Credito donde corresponde: estas correcciones existen porque nuestra propia auditoria de validez senalo los numeros primero.
Actualización, 2026-08-16: el techo nativo de contexto, gratis
Una noche después, el mismo equipo sirve el modelo a su contexto nativo completo de 262.144 tokens — 2,7 veces el contexto reportado arriba — con la banda de decodificación en caliente sin cambios (148-163 tok/s) y el tiempo-por-tarea igual o más rápido. Toda la ganancia viene de cuantizar la caché KV: K y V en q8_0 reducen la caché a la mitad, así que 262k de KV cuantizada ocupa menos memoria que 96k en f16. La escalera (96k → 160k → 192k → 262k) se validó con gates en cada escalón sobre la batería de tareas reales, con un costo etiquetado honestamente: el prefill baja de ~390 a ~299 tok/s. La unidad de rollback queda guardada. Escalera completa: el repo.