5 puntos por GN⁺ 2026-03-23 | 1 comentarios | Compartir por WhatsApp
  • Motor de inferencia basado en C/Metal que ejecuta un modelo Mixture-of-Experts de 397B parámetros en una MacBook Pro (48GB RAM) a más de 4.4 tokens por segundo
  • Implementado únicamente con C y shaders de Metal, sin Python ni frameworks, mientras transmite por streaming el modelo completo de 209GB desde el SSD
  • Maximiza la eficiencia paralela de GPU·SSD·CPU con SSD Expert Streaming, kernels optimizados con FMA y Deferred GPU Compute
  • La configuración con cuantización de 4-bit logra un equilibrio entre calidad y velocidad, con generación de salida de nivel de producción, incluida la función de llamadas a herramientas
  • Un caso de reducción y optimización que hace posible la inferencia en tiempo real de modelos MoE gigantes incluso en una laptop

Resultados de rendimiento

  • La configuración de expertos de 4-bit (kernel FMA) alcanza 4.36 tok/s, con buena calidad, usando los 209GB completos en disco
  • La configuración base de 4-bit logra 3.90 tok/s, como etapa previa a la optimización con FMA
  • La configuración de expertos de 2-bit (trust the OS) alcanza 5.74 tok/s y es más rápida, pero los errores en la salida JSON impiden las llamadas a herramientas
  • El pico de un solo token en 2-bit llega hasta 7.05 tok/s, pero no es adecuado para uso real
  • La cuantización de 4-bit es la configuración más adecuada para operación real

Entorno de hardware

  • MacBook Pro (Apple M3 Max), CPU de 16 núcleos (12P+4E), GPU de 40 núcleos, ANE de 16 núcleos
  • 48GB de memoria unificada, con un ancho de banda de aproximadamente 400GB/s
  • SSD Apple Fabric de 1TB, con 17.5GB/s de lectura secuencial
  • Entorno macOS 26.2 (Darwin 25.2.0)

Arquitectura del modelo

  • Un total de 60 capas transformer: 45 de GatedDeltaNet (atención lineal) + 15 de atención completa
  • Cada capa tiene 512 expertos, y se activan K=4 por token (incluido 1 experto compartido)
  • Dimensión oculta 4096
  • Tecnologías clave

    • SSD Expert Streaming

      • Carga los pesos de los expertos (209GB en 4-bit) desde NVMe SSD según se necesitan mediante pread() en paralelo
      • En cada capa solo se cargan los 4 expertos activos (aprox. 6.75MB cada uno)
      • La page cache del sistema operativo gestiona automáticamente el caché, sin necesidad de uno adicional
      • Arquitectura inspirada en el paper de Apple “LLM in a Flash
    • Kernel de dequantización optimizado con FMA

      • Reorganiza la operación (nibble * scale + bias) * x a la forma fma(nibble, scale*x, bias*x)
      • Precalcula scale*x y bias*x para que las unidades FMA de la GPU lo ejecuten en una sola instrucción
      • 12% de mejora de velocidad frente a una implementación simple
    • Metal Compute Shaders

      • Implementa con kernels Metal escritos a mano operaciones como producto matriz-vector de dequantización 4-bit/2-bit, activación SwiGLU, normalización RMS, atención en GPU (Q@Kᵀ, softmax, scores@V), RoPE y combinación MoE + residual + gate
    • Deferred GPU Expert Compute

      • Envía de forma asíncrona el comando CMD3 (forward pass de expertos) para que la CPU prepare la siguiente capa mientras la GPU ejecuta
      • Las operaciones de combinación + normalización + residual también se ejecutan en la GPU y se pasan directamente a la siguiente capa
    • Uso de Accelerate BLAS

      • Usa cblas_sscal, cblas_sgemv, cblas_sger para el cálculo recurrente de GatedDeltaNet
      • 64% más rápido que el código escalar
    • Trust the OS

      • Elimina el caché personalizado y deja el caché de los datos de expertos a la page cache del sistema operativo (basada en LRU, aprox. 35GB)
      • Resultó más rápido que un LRU propio en Metal, un caché con malloc o un caché comprimido con LZ4
      • Logra una tasa natural de aciertos de caché del 71%
  • Restricciones de memoria unificada

    • En Apple Silicon, el DMA del SSD y el cómputo de la GPU comparten el mismo controlador de memoria
    • En ejecución paralela, la saturación del ancho de banda de la GPU provoca un fuerte aumento de latencia
    • Un pipeline secuencial GPU → SSD → GPU es la forma óptima para este hardware

1 comentarios

 
GN⁺ 2026-03-23
Comentarios en Hacker News
  • Hay otra forma de ejecutar Qwen 3.5 397B incluso en dispositivos de consumo
    Existe una versión con cuantización de aproximadamente 2.5 BPW (quant), así que también es totalmente posible en equipos con 128 GB de memoria
    Yo lo corrí bien en un M1 Ultra a unos 20 tok/s, manteniendo un contexto de 256k
    Los resultados de lm-evaluation-harness fueron más o menos: mmlu 87.86%, gpqa diamond 82.32%, gsm8k 86.43%, ifeval 75.90%
    Dejé una explicación más detallada de mi experiencia en enlace 1 de la discusión en Hugging Face y enlace 2
    Es un excelente modelo para inferencia offline

    • El método del enlace también ya usa cuantización de 2 bits
      Reduce la cantidad de expertos por token de 10 a 4, así que la calidad baja todavía más
      Para prompts cortos está bien, pero en sesiones largas ya no sirve
      También tiene el problema de generar "name" en vez de \name\ en la salida JSON, lo que vuelve inestable la llamada de herramientas
    • Me pregunto cuántos tok/s da hoy en día
      También quisiera saber si sigue funcionando bien con contextos largos
      Y qué gusto ver tu apodo después de tanto tiempo: fuiste quien creó Neovim, qué éxito tan impresionante
      Yo también lo uso todos los días
    • Me da curiosidad el consumo de energía
      Tal vez se podría estimar con CoconutBattery
    • Me pregunto si lo corrieron solo en un único M1 Ultra
    • Estaba gastando demasiados créditos en automatización personal, así que esta información me ayuda muchísimo
  • Viendo los detalles, parece que lograron alrededor de 5 tok/s usando cuantización de 2 bits y reduciendo los expertos de 10 a 4
    Es una prueba de concepto interesante, pero está bastante lejos de la calidad del modelo 397B original
    Este tipo de optimizaciones extremas termina causando una pérdida de inteligencia en el modelo
    También está el problema de que genera "name" en vez de \name\ en la salida JSON, así que no sirve para uso real
    Reconozco que demuestra que este tipo de experimento es técnicamente posible, pero no está en un nivel realmente utilizable
    Últimamente ya me cansé de ver tantos papers escritos por IA

    • Al ver el problema con la salida JSON, pensé que tal vez bastaría con restringir el muestreo solo a tokens JSON válidos
      Pero he escuchado que incluso los LLM comerciales tienen baja precisión en tool calling
      Supongo que debe de ser algo difícil de implementar o estructuralmente imposible en alguna parte
  • También hubo discusión relacionada en r/LocalLLaMA

  • Según la página de GitHub, el acceso simple por mmap se vuelve un cuello de botella por la sobrecarga a nivel de página
    Me pregunto si en macOS se podría mejorar configurando huge page o haciendo prefetch con posix_fadvise

  • La pérdida de calidad con cuantización de 2 bits sí es un problema serio
    En tareas reales, he visto que un modelo 30B de 4 bits bien afinado rinde mejor que uno de 70B+ a 2 bits
    Si reduces la cantidad de expertos, en la práctica termina siendo otro modelo
    Aun así, es interesante que estén poniendo a prueba los límites del hardware de consumo

  • Cansa que el título “ejecutarlo en una laptop” casi siempre termine significando una MacBook de $3000
    La tecnología de compresión es impresionante, pero no es una opción realista para el usuario común

    • Yo uso una laptop bastante decente (no es Mac), así que este tipo de intentos me parecen interesantes
      Pero al ver el título no espero que vaya a correr en cualquier laptop
      Prefiero disfrutar estos experimentos en vez de reaccionar con demasiado cinismo
    • Se puede conseguir una M1 Max de 64 GB usada por menos de $2000
      También hay mucha gente que ya tiene MacBooks potentes así por edición de video y otros usos
      La ventaja es poder experimentar con la laptop que ya tienes, sin equipo adicional
    • De hecho, también se puede con una laptop Strix Halo de $3000 a $4000
    • El título habría sido más preciso si dijera algo como “,on a laptop!”
    • Yo corrí el modelo completo con un clúster de dos laptops de $3000 (zbook de 128 GB)
      Me dio alrededor de 20 tok/s, y me parece un nivel bastante accesible incluso para una persona
      Incluso valió la pena como inversión de trabajo
  • No Python. No frameworks. Just C, Objective-C, and hand-tuned Metal shaders.
    Apenas leí esa frase, enseguida me imaginé de dónde habían salido los tokens

  • Dicen “Hand-written Metal kernels”, pero ¿no habrá sido GPT quien los escribió? 😉

    • De hecho, el autor aclara explícitamente que es código escrito por IA
  • Es un resultado realmente impresionante
    Me pregunto si en Linux se podría hacer algo parecido, usando acceso basado en memoria del sistema en vez de SSD
    O incluso suena interesante la idea de guardar los pesos en una especie de ROM

    • El mismo enfoque también es posible en Linux
      Solo que este proyecto usa Metal, así que está limitado a macOS
    • La mayoría de los motores (por ejemplo, llama.cpp, vllm, sglang) ya soportan este tipo de función
      Pero los modelos MoE siguen teniendo una limitación fuerte de ancho de banda
    • La función de cargar expertos en memoria del sistema ya está disponible en la mayoría de los frameworks locales de IA
      Pero en la etapa de decodificación, la sobrecarga de transferir desde CPU termina siendo mayor que usar GPU, así que la ganancia es poca
      Lo más eficiente es usar la GPU solo para acelerar la parte compartida
    • También se puede ejecutar en CPU algunas capas que no caben en la memoria de GPU, pero
      cuando el modelo se va a la RAM del sistema o al disco, el rendimiento cae de forma drástica
    • Si este enfoque funciona, parecería posible hacer inferencia grande a nivel de laboratorio personal con dos 3090 y suficiente RAM
  • Se mencionó que el SSD era el cuello de botella, pero el autor dijo que obtuvo 15 GB/s
    Según yo, el ancho de banda máximo era de unos 8 GB/s. ¿Qué se me está escapando?

    • En una arquitectura como esta, el IO es muy ráfaga-dependiente
      Cuando sale el resultado del router, se cargan los expertos desde el SSD y en ese momento el SSD se satura
      El IO promedio ronda los 2970 MB/s, bastante por debajo del límite del SSD
      Quizá sería mejor paralelizar algunos tensores con lecturas asíncronas
      Cuando experimenté con io_uring en Linux, cerca de un 20% de las lecturas terminaban en paralelo mientras se hacía el cómputo
    • Con PCIe 5 el ancho de banda se duplica, así que los SSD más nuevos son más rápidos
    • Los MacBook Pro M5 Pro/Max tienen velocidades de SSD de ese nivel