- En un servidor con doble Xeon E5-2690 v2 de 2013 y DDR3, se ejecutó Gemma 4 26B-A4B Q8_0 solo con CPU, logrando cerca de 5.2 tokens/s en decodificación y alrededor de 16 tokens/s en evaluación de prompts
- La ruta rápida de
ik_llama.cpppresupone AVX2 y FMA3, pero las CPU Ivy Bridge solo soportan AVX1, por lo que hicieron falta cambios de compilación y fallbacks de operaciones para una compilación sin AVX2 - Mientras el generador de grafos creaba incondicionalmente
MOE_FUSED_UP_GATEyFUSED_UP_GATE, el despachador sin AVX2 no tenía una ruta para procesarlas, lo que dejaba unos 240 tensores sin calcular en cada pasada hacia adelante y producía salidas multilingües caóticas - Claude encontró el error mediante instrumentación de logits y análisis de código, reemplazó la operación fusionada por dos
ggml_mul_mat_idyggml_fused_mul_unary, mientras que el usuario ejecutó los experimentos y determinó el criterio para un resultado correcto - Los servidores empresariales antiguos también pueden servir como alternativa local ante fallas de API de pago o para trabajos batch lentos, pero no se debe usar
--run-time-repack, que crea un layout exclusivo para AVX2
Entorno de ejecución de un servidor de almacenamiento de hace 13 años
- El equipo HP StoreVirtual reutilizado usa doble Xeon E5-2690 v2 de 2013 y memoria DDR3, sin GPU
- Al ser de la generación Ivy Bridge, solo soporta AVX1 y no soporta AVX2 ni FMA3
- Originalmente fue fabricado para almacenamiento en disco y costó menos de 300 dólares
- El modelo ejecutado es Gemma 4 26B-A4B de Google, un modelo de mezcla de expertos (MoE) de pesos abiertos con 26 mil millones de parámetros
- En el modelo cuantizado Q8_0, la decodificación se midió en cerca de 5.2 tokens/s y la evaluación de prompts en alrededor de 16 tokens/s
El caso de Xeon de 2016 que sirvió como punto de partida
- A 10 year old Xeon is all you need, compartido en Hacker News, es un caso en el que Gemma 4 se ejecutó sin GPU en un Xeon único de 2016 con 128 GB de DDR3
- Esa configuración usa ik_llama.cpp y unas 25 flags de ejecución finas
- Decodificación especulativa
- Enrutamiento MoE considerando la CPU
- Flash attention para CPU
- Reempaquetado de pesos en tiempo de ejecución
- Se intentó aplicar el mismo enfoque al servidor Ivy Bridge, pero la ejecución se detenía en la fase inicial
- A diferencia de la CPU Broadwell de 2016, el E5-2690 v2 no tiene AVX2 ni FMA3
- Ese conjunto de instrucciones está disponible desde Haswell de 2014, es decir, la generación v3 de Intel, y los kernels rápidos estaban escritos asumiéndolo
Diagnóstico y parche con Claude
- Al recibir la información de la falla inicial, Claude identificó como causa la diferencia en el conjunto de instrucciones de la CPU
- Continuando un enfoque incompleto que antes se había intentado con un modelo gratuito, modificó rutas críticas de rendimiento en C++ para que hicieran fallback correctamente en CPU anteriores a AVX2
- El trabajo no terminó con una única solicitud de
fix it- Leyó código C++ orientado a rendimiento escrito por otro desarrollador
- Analizó por qué el kernel no era válido en una microarquitectura específica
- Evitó rutas no soportadas sin descartar las optimizaciones existentes del fork
- En lugar de escribir directamente los fallbacks de kernels C++, el usuario ejecutó experimentos, leyó las salidas, definió las siguientes preguntas y cumplió el rol de determinar el criterio para un resultado correcto
- El diagnóstico y el parche fueron realizados por una instancia de Claude ejecutada en ese servidor
Ruta de operaciones rota en la compilación sin AVX2
ik_llama.cpp, usado para la inferencia MoE de Gemma 4, es un fork dellama.cppy por defecto asume AVX2 como requisito mínimo- Al desactivar
GGML_USE_IQK_MULMATdurante la compilación, se excluye la mayoría de las rutas rápidas y se hace fallback a operaciones escalares/SSE generales- Para la multiplicación de matrices Q8_0 habitual, este fallback funciona
- Sin embargo, en dos operaciones del grafo el fallback no se aplicaba
- La red feed-forward MoE de Gemma 4 genera las siguientes operaciones
MOE_FUSED_UP_GATE: operación que combina la multiplicación de matrices gate·up por experto y SwiGLUFUSED_UP_GATE: versión de operación densa usada en capas no MoE
- En el despachador de cómputo, ambas operaciones estaban protegidas por la condición
GGML_USE_IQK_MULMAT, pero el generador de grafos creaba las operaciones sin condición- En el despachador de una compilación sin AVX2 no había ningún
caseque manejara esos enum - Al caer en la rama por defecto, los tensores destino de todas las redes feed-forward de expertos quedaban silenciosamente sin calcular
- En el despachador de una compilación sin AVX2 no había ningún
- Gemma 4 26B usa 8 expertos activos por token en 30 capas, por lo que en cada pasada hacia adelante terminaba consumiendo unos 240 tensores con valores que habían quedado en buffers de memoria
Pistas reveladas por una salida caótica
- La salida errónea parecía fluida, pero era una cadena multilingüe sin sentido
- Los ID de tokens se distribuían de forma uniforme por todo el vocabulario de 262,000 elementos
- Tailandés, coreano, centinelas
<unused>, fragmentos en inglés, etc., se generaban con frecuencias similares
- Con temperatura 0, la salida era determinista; los resultados con un solo hilo y con múltiples hilos eran idénticos byte por byte y no aparecían NaN
- Se observaba que una constante grande empujaba el estado oculto en cada capa, aplanando el softmax final
- Claude instrumentó los logits crudos antes del muestreo para imprimir los 5 tokens principales, el rango, el promedio y el número de NaN
- El logit promedio del primer token predicho no estaba cerca de 0, sino en +16
- Cerca del 80% de todo el vocabulario tenía logits positivos
- Como el sesgo era constante, a diferencia de una corrupción aleatoria, se acotó la causa a que una gran parte del estado oculto estaba usando memoria no inicializada con pequeños valores positivos de punto flotante remanentes
Corrección en tres etapas
- El parche está compuesto por tres commits encima de
maindel fork -
Corrección de compilación sin AVX2
- Las ramas escalares
#elsedequantize_row_q8_0_x4yquantize_row_q8_1_x4_Teniqk_quantize.cppen realidad referenciaban helpers AVX2 comohsum_i32_8 - Esas ramas se reescribieron como bucles escalares portables
- Se agregaron condiciones de protección
#if GGML_USE_IQK_MULMATa algunas llamadas IQK que se habían filtrado aggml.cyggml-quants.c - Se agregó un include faltante para que
iqk_cpu_ops.cppcompilara de forma independiente - Sin esta corrección, el fork en sí no compila en hardware sin AVX2
- Las ramas escalares
-
Fallback del grafo en tiempo de ejecución
- En lugar de corregir el despachador, se cambió el generador de grafos para que en esa compilación genere operaciones que ya tienen rutas de cálculo
- En
ggml_moe_up_gate, cuandoGGML_USE_IQK_MULMATestá desactivado, se procesan los pesos combinadosup_gate_exps - La forma del tensor es
[n_embd, 2*n_ff, n_experts], donde la primera mitad es gate y la segunda mitad es up - Se separa en dos slices con
ggml_view_3d - Se ejecuta
ggml_mul_mat_iden cada slice - Se combinan los dos resultados con
ggml_fused_mul_unary(gate, up, SILU) - Si los pesos gate y up ya están separados, se usan dos
ggml_mul_mat_idy una operación fusionada de multiplicación y unaria, sin slicing - El mismo fallback se aplicó también a
ggml_fused_up_gate, usado en capas no MoE mul_mat_idusa la implementación base de ggml, yfused_mul_unaryprocesa SILU y la multiplicación de una vez, por lo que todas las operaciones componentes ya tienen una implementación no IQK- Todo el cambio está detrás de
#if !GGML_USE_IQK_MULMAT, de modo que los resultados de compilaciones con AVX2 son idénticos bit a bit a los existentes
-
Limpieza de stubs de CI
- Los stubs
#elsede las fuentes IQK diferían deiqk_mul_mat.h, por lo queci/run.shtampoco compilaba en hardware sin AVX2 - Faltaba el include
<cstdint> - Algunos stubs tenían firmas distintas, como un parámetro inicial innecesario o la ausencia del parámetro
sinks - Algunas funciones no tenían stub, lo que provocaba referencias indefinidas en la etapa de enlace
- Al alinear los stubs con el header, se volvió posible ejecutar la suite de pruebas también en entornos sin AVX2
- Los stubs
Costo de rendimiento del fallback y error de reempaquetado
- El fallback ejecuta dos
mul_mat_iden lugar de un solo kernel fusionado, por lo que tiene un costo adicional - Esa CPU ya está limitada por el ancho de banda de memoria, y el kernel fusionado original también era exclusivo para AVX2, así que en este entorno no había una ruta de ejecución existente que se estuviera abandonando
- El rendimiento final en el MoE 26B-A4B es de cerca de 5.2 tokens/s en decodificación y alrededor de 16 tokens/s en evaluación de prompts
--run-time-repackreordena al inicio los pesos cuantizados al formato intercalado exclusivo de AVX2Q8_0_R8- En un entorno AVX1, es un bug separado que vuelve a corromper la salida
- El parche actual no lo corrige y elimina esa flag del script de ejecución
Proceso para acotar la causa
- La incompatibilidad del conjunto de instrucciones se comprobó fácilmente, pero el problema de que el despachador cayera en la rama por defecto sin error fue difícil de encontrar
- La revisión de código descartó varios candidatos
- Los helpers de RMSNorm parecían correctos
- El fallback AVX1 de
ggml_vec_dot_q8_0_q8_0también parecía correcto - Como los resultados de un solo hilo eran idénticos bit a bit, se descartó un error de threading
- A partir de que el promedio de logits quedaba fijo en +16 y los tokens de cola larga tenían valores similares, se concluyó que una gran parte del flujo residual no estaba inicializada
- Tras buscar
#if GGML_USE_IQK_MULMATen el despachador, en aproximadamente un minuto se encontraron las dos rutas de operación faltantes
Condiciones de reproducción y alcance de uso
- Las condiciones de reproducción en equipos previos a AVX2 son las siguientes
- Hardware: doble Xeon E5-2690 v2, Ivy Bridge, AVX1, DDR3, sin GPU
- Compilación: compilar
ik_llama.cppde la rama parcheada sinGGML_USE_IQK_MULMAT - Modelo: Gemma 4 26B-A4B Q8_0
- Ejecución: usar las flags habituales de CPU de
ik_llama.cpp, pero excluir--run-time-repack
- Los cambios exactos pueden verse en ikawrakow/ik_llama.cpp PR #2138
- Al momento de escribir, aún está abierto y esperando revisión de los maintainers, por lo que debe ejecutarse directamente desde la rama
- Los bugs que aparezcan en el mismo equipo pueden reportarse en el hilo del PR
- Mantener un modelo local en servidores empresariales antiguos permite usarlo como alternativa cuando se cae una API de pago, o procesar trabajos batch lentos para los que el cobro por token no encaja
- Se valora más la capacidad de adentrarse directamente en código desconocido y sistemas antiguos que usar servicios de suscripción, y esto se aplica de la misma forma al mantenimiento de una aplicación Rails de hace 15 años o de una base de datos cuyo responsable ya se fue
1 comentarios
Comentarios de Hacker News
Se espera que para mediados de 2027 sea posible ejecutar modelos MoE de más de 200 mil millones de parámetros en hardware de consumo común
Estoy ejecutando localmente Qwen3.6-35B-A3B en una Mac de 16GB y obtengo entre 7 y 9 tokens por segundo: https://github.com/deepanwadhwa/samosa-chat
Básicamente, eso significa correr localmente en una MacBook Air con 16GB de RAM un modelo de nivel GPT-4 a esa velocidad
Ya está en un rango similar al número de parámetros activos de la mayoría de los modelos de más de 200 mil millones, así que Prism podría sacar uno de ese tipo si quisiera. Eso sí, las redes neuronales recurrentes como HRM no necesitan tantos parámetros, así que se puede debatir si realmente hace falta llegar a esa escala: https://huggingface.co/sapientinc/HRM-Text-1B
Por ejemplo, si en cada capa solo se guarda una semilla de 256 bits y se mete en una función de ruido para generar 16K pesos reales, el almacenamiento por peso podría bajar a menos de 1 bit
Tengo muchas ganas de ver los nuevos modelos que parecen venir este mes y el siguiente, porque podrían cambiar por completo el panorama. Definitivamente vale la pena probar Ornith
Aunque a algunos no les guste oírlo, creo que el costo por token de los proveedores de inferencia es más barato que la electricidad de correrlo localmente
Simplificando y contando solo la generación de salida, 5 tokens por segundo son 18,000 tokens por hora, y el costo con un proveedor sería de unos 0.005 dólares. Si asumimos que el servidor consume unos 500W durante la inferencia y tomamos como referencia Alemania, donde la electricidad cuesta 0.3 dólares por kWh, generar esa misma cantidad localmente costaría 0.15 dólares, o sea 30 veces más caro
Si te preocupa la privacidad, correrlo localmente sigue siendo buena opción, pero hay que tener claro que es mucho menos eficiente que un proveedor de inferencia. A medida que las GPU nuevas mejoren la eficiencia de inferencia, esta brecha también se va a ampliar bastante
Al principio calculé mal y puse 180 mil tokens, pero en realidad son 18,000 tokens, así que salvo que la electricidad te salga casi gratis, es difícil competir. Además, los proveedores todavía usarán H200/H100 para modelos pequeños, pero cuando se pasen a GB300 o a las GPU Ruby del próximo año, el costo de inferencia podría bajar a una trigésima parte, y el valor principal de los modelos locales probablemente será la privacidad
En una hora puede procesar 3.6 millones de tokens de entrada o generar 144,000 tokens, y el costo eléctrico es de unos 0.15 dólares. Con Sonnet, procesar esa misma cantidad costaría 7.2 dólares en entrada y 1.4 dólares en generación, así que la nube sale 10 veces más cara para generar y casi 50 veces más cara para procesar
Los proveedores de inferencia están compitiendo por cuota de mercado mientras cargan con deudas enormes, así que claramente los precios van a subir
Si democratizamos la IA hasta el punto de que la comunidad la controle directamente, también se podría resolver el problema de los centros de datos, y el nivel de censura y alineación podría decidirse democráticamente dentro de la comunidad. Es una idea parecida a algunas cosas que ha escrito Geohotz
Los modelos open source pronto serán lo bastante buenos y eficientes como para ofrecer servicio barato con hardware usado. En cada comunidad pequeña, con que haya una persona con conocimientos técnicos y se junten unos cientos de dólares de costo inicial, después se podría operar casi gratis, sin pagar electricidad
https://solar.lowtechmagazine.com/
Si no existiera la opción local, los precios de los modelos en la nube serían mucho más altos
Es probable que los Xeon duales de esta generación consuman más de 300 W bajo carga. Con la tarifa eléctrica promedio de EE. UU., eso serían 1.35 dólares al día, y más si además hay que enfriar el espacio en verano
Ignorando el tiempo de procesamiento del prompt, incluso corriéndolo 24 horas al día serían unos 400 mil tokens diarios, así que el costo sería de unos 0.30 dólares por cada millón de tokens de salida. Curiosamente, eso coincide con el precio actual de este modelo en OpenRouter, pero la velocidad de generación en OpenRouter es 8 veces más rápida
Hay muchas razones para experimentar con LLM locales, como evitar que los datos salgan de tu casa, pero es difícil que convenga económicamente. Habiendo invertido bastante más dinero en equipo de inferencia local en casa, diría que es divertido, pero no una forma de ahorrar
Se resumieron resultados de ejecutar varios modelos sin GPU, con Xeon dual y 256 GB de DDR4
https://gist.github.com/hparadiz/f3596d00a62d8ebb2dadcc46ee5822c7
Es bastante lento. Yo estoy obteniendo 8 a 12 tokens por segundo incluso en un CPU de 13 años, aunque puede variar según el tamaño del contexto y otras configuraciones
https://news.ycombinator.com/item?id=48354801
gemma4:e2bygemma4:12b-it-qaten OllamaSoy el autor del post original. Parece que mi comentario original fue reportado por alguna razón. Dejé las correcciones en el PR #2138 del proyecto padre: https://github.com/ikawrakow/ik_llama.cpp/pull/2138
Este equipo StoreVirtual no parece tener puertos útiles para instalar software. Solo veo algo como puertos USB; me pregunto si la instalación se hace por consola serial
Estoy ejecutando Gemma 4 26B en una Mac Pro 2013 con la misma configuración y obtengo alrededor de 5 tokens por segundo. Las tarjetas gráficas duales aquí no sirven de mucho, pero para algunas tareas sigue siendo bastante útil
Pienso probarlo yo mismo cuando llegue el viernes, así que tengo ganas de verlo
https://echalupa.com/blog/mac-pro-6-1-llama-cpp-firepro-d300-vulkan-ubuntu
https://matthewgribben.com/blog/mac-pro-6-1-llama-cpp-firepro-d700-vulkan-ubuntu
Vi en persona la configuración del sótano y la verdad está impresionante. La próxima vez estaría bueno que también mostraras la impresora 3D
Como video medio relacionado, alguien ejecutó un LLM en un Pentium 4 y le puso el apodo NetburstGPT. Claro, es lentísimo
https://www.youtube.com/watch?v=ILV-eu90te8