1 puntos por GN⁺ 2 시간 전 | 1 comentarios | Compartir por WhatsApp
  • WASTE es un motor de inferencia en C que convierte el modelo completo de pesos abiertos Kimi K3 de 2.78 billones de parámetros en un contenedor de 982 GiB sin reducción, para ejecutarlo en laptops de consumo
  • Mantiene en memoria solo el trunk residente del modelo y lee desde NVMe alrededor de 4% de los pesos expertos activados por token, mientras que la RAM restante se usa como caché de expertos de tamaño limitado
  • Kimi K3 puede abrirse con un mínimo de 29.05 GB de RAM en contexto 4K, pero la configuración práctica usa un presupuesto de 46 GB en una MacBook Pro de 64 GB, donde registra 0.45~0.62 tok/s
  • Superpone lecturas de expertos y cómputo para una mejora de alrededor de 1.6x, y ejecuta el router de la siguiente capa un residual antes para elevar la tasa de aciertos de caché de 14% a 38%, sin cambiar ni el volumen total leído ni los logits
  • Permite ejecutar localmente modelos gigantes sin conexión a internet, sin costo por token ni transferencia de datos a terceros, pero requiere NVMe interno y cerca de 1 TB de almacenamiento, y si el presupuesto de RAM supera los 52 GB puede volverse mucho más lento por la paginación del sistema operativo

Objetivo de WASTE y forma de implementación

  • WASTE (Weight-Aware Streaming Tensor Engine) es un motor de inferencia en C integrable y sin dependencias externas en tiempo de ejecución
    • Solo usa libwaste.a y el ejecutable waste, y no requiere BLAS, CUDA, ONNX ni Python aparte de libc y pthreads
    • Python solo se usa para la conversión del modelo y la validación de referencia con PyTorch; no entra en la ruta de inferencia
    • La API pública consta de 26 funciones y soporta abrir el modelo, fijar el límite de RAM, generar, guardar sesiones y cerrar
  • El objetivo de validación actual es el modelo completo Kimi K3 2.78T
    • La fuente pública ocupa 1.42 TB y el contenedor convertido queda en 982 GiB
    • No es una versión destilada, podada ni reducida
    • Kimi-Linear 48B también usa el mismo motor y formato, con un contenedor de 19 GiB, mínimo de 1.87 GB de RAM y 10.7 tok/s
  • El nombre del proyecto surge del objetivo de reducir la situación en la que modelos que podrían ejecutarse en hardware de escritorio se corren en centros de datos en la nube consumiendo tanto costo por token como energía

Estructura de streaming desde disco

  • Como K3 usa una arquitectura Mixture of Experts, solo se activa alrededor de 4% del modelo por token, así que los pesos inactivos no necesitan permanecer en RAM y se acomodan para poder accederse justo cuando se requieren
  • El contenedor .waste está compuesto por un manifiesto JSON, un trunk residente y bancos de expertos por capa
    • Cada registro de experto está alineado a 4 KiB
    • Las matrices gate, up y down se colocan contiguas para leer un experto exacto con una sola llamada a pread
    • La caché de páginas se evita con F_NOCACHE en macOS, O_DIRECT en Linux y FILE_FLAG_NO_BUFFERING en Windows
  • Si no se evita la caché de páginas, un contenedor de prueba más pequeño que la RAM puede entrar en la caché del sistema operativo y producir tasas de acierto que no se reproducen con el modelo de 982 GiB
  • Al leer registros, siempre se verifican el magic, el ID del experto y el rango de offsets para evitar que bancos truncados o mal ensamblados respondan con pesos incorrectos
    • La verificación crc32 del payload se activa con --verify
    • El costo de verificación es de alrededor de 5% en Kimi-Linear y de alrededor de 1% en K3; por defecto está desactivada
    • Se recomienda verificar una vez los contenedores copiados, descargados o ubicados en discos no confiables
    • El trunk y los codebooks no tienen checksum

Lectura anticipada y predicción del router

  • Cuando el router de una capa determina 16 IDs de expertos, cada lectura se solicita en un hilo separado y el cómputo consume los datos a medida que llegan
    • La superposición entre lectura y cómputo mejora alrededor de 1.6x en K3
    • El trabajo realizado y las estadísticas de caché son iguales antes y después de activar esta función
  • Antes de que se genere el hidden state real de la siguiente capa, se ejecuta el siguiente router residente usando el hidden state actual para traer por adelantado 6 expertos
    • La predicción con un residual de anticipación tiene 92% de precisión en rank 1 y 81% en el top 6
    • Como el router real decide a los expertos finales, la salida se mantiene exactamente correcta
    • La demand hit rate sube de 14% a 38% y el total de bytes leídos no cambia
    • Puede desactivarse con WASTE_LOOKAHEAD=0
  • Se eliminó una implementación que aplicaba la misma técnica al prefill
    • Las capas decode ocupan 16 slots de caché, pero las chunk layers ocupan alrededor de 550
    • Los registros precargados eran expulsados antes de usarse, lo que aumentó el volumen leído en 6.9% y no redujo el tiempo

Cuantización y precisión

  • Los pesos de expertos se almacenan como cuantización vectorial residual de 3 etapas con codebooks de 256 entradas para vectores de 8 dimensiones, usando 3.00 bits por peso
    • En lugar de reconstruir la matriz completa, se construye una tabla de productos internos parciales y luego cada fila se procesa con 3 consultas a la tabla y 2 sumas
  • El trunk mantiene 4 bits y 8 bits
    • Como el modelo fue entrenado con conciencia de cuantización solo para expertos, con trunk de 3 bits la salida colapsa
    • La predicción de caché acertaba, pero como tampoco mejoraba el rendimiento, se eliminó
  • Todas las capas se compararon con una implementación de referencia en PyTorch
    • La diferencia final de logits es 3.6e-06
    • La torre de visión coincide con su propia referencia a 2.3e-06
    • La transformación de la caché latent KV mantiene logits idénticos al nivel de 1.2e-05

Presupuesto de RAM y rango estrecho de rendimiento

  • K3 usa 16 expertos por cada una de sus 92 capas, formando un working set de 17.0 GB por token
    • Si la caché es menor que ese tamaño, los expertos almacenados en un token se expulsan antes del siguiente token y la tasa de aciertos cae a 0%
  • Las mediciones en un sistema de 64 GB muestran que asignar más RAM no siempre lo hace más rápido
    • Presupuesto de 32 GB · caché de 3.32 GB: tasa de aciertos 0%, 0.50 tok/s
    • Presupuesto de 46 GB · caché de 17.32 GB: tasa de aciertos base 17%, 0.53~0.55 tok/s
    • Presupuesto de 52 GB · caché de 23.32 GB: 0.04~0.15 tok/s, no reproducible
    • Presupuesto de 58 GB · caché de 29.32 GB: 0.02~0.03 tok/s
  • El lookahead del router eleva la tasa de aciertos de alrededor de 14% a 38% con 46 GB, pero el colapso por encima de 52 GB no se debe a cache misses sino a la paginación del sistema operativo
    • A 58 GB, aunque la tasa de aciertos es mayor, sigue siendo unas 20 veces más lento que a 46 GB
    • Si se fuerza al sistema a entrar en paginación con un presupuesto grande, hasta la medición de 46 GB puede caer a 0.02 tok/s
  • El presupuesto predeterminado se elige por debajo de 7/8 de la RAM física y se ajusta a unidades del working set por token
    • En una MacBook Pro de 64 GB se usan 46.24 GB y se asignan 17.56 GB a la caché de expertos
    • Si el presupuesto explícito es menor que el mínimo, el inicio se rechaza en lugar de continuar con swapping
    • En un sistema de 128 GB puede usarse el presupuesto total recomendado equivalente al trunk más 3 veces el working set

Rendimiento de K3 y requisitos de hardware

  • El sistema de medición es una MacBook Pro M5 Pro de 64 GB con SSD interno
    • RAM mínima para contexto 4K: 29.05 GB
    • 32K: 30.54 GB, 128K: 35.63 GB, 1M: 83.21 GB
    • Trunk residente: 27.28 GB
    • Carga del modelo: 20 segundos
    • decode: 0.45~0.62 tok/s con el presupuesto predeterminado
    • prefill: 0.47 tok/s con chunking, 0.29 tok/s secuencial
  • Aunque el modelo puede abrirse con el mínimo de 29.05 GB, un sistema de 32 GB puede paginar fuertemente, así que 64 GB es la recomendación real
  • En estado cold se leen 17.0 GB de expertos por token, y con una tasa de aciertos de 38% por lookahead se leen 10.5 GB
  • El SSD interno se midió en 12.78 GB/s y una carcasa USB externa en 0.94 GB/s
    • Como un solo token lee 17 GB de expertos, el mismo procesamiento tarda unos 13 segundos en almacenamiento externo
    • La descarga original puede guardarse en disco externo, pero el contenedor convertido debe estar en NVMe interno
  • Se requieren 982 GiB para el contenedor convertido y 1.42 TB para el staging de los shards originales; el espacio de staging puede liberarse después de la conversión

Attention y procesamiento multimodal

  • El attention de K3 combina Kimi Delta Attention y gated multi-head latent attention en proporción 3:1
    • KDA mantiene un estado recurrente de tamaño fijo en vez de una caché KV creciente
    • MLA almacena en caché un latent de ancho 512 sin expandir key/value por head
  • Al absorber kv_b_proj en query y output, la caché para contexto 4K baja de 11.25 GB a 0.21 GB
    • Eso representa una reducción de 53x
    • En 128K, el layout expandido requiere 360 GB y el layout latent 7.2 GB
  • La ruta multimodal soporta un ViT de 401 millones de parámetros, 27 capas y patch 14
    • La codificación de una imagen de 1024 patches tarda 15.7 segundos
    • Una imagen de 896×896 ocupa 256 posiciones de secuencia en la configuración predeterminada
    • Como los embeddings de imagen también pasan por las 92 capas MoE, la mayor parte del costo es igual al text prefill más que a la torre de visión
    • Si se reduce a la mitad max_patches en vision.json, también se reduce a la mitad el número de posiciones del prompt
  • Soporta PNG, JPEG, GIF, BMP, TGA y PSD, y puede usar imágenes en run, chat y eval
    • Las posiciones de imágenes codificadas durante la conversación permanecen en el attention state y no se recodifican en el siguiente turno
    • La torre de visión solo se carga cuando hay imágenes, y usa 434 MB de pesos y 1.12 GB de memoria reservada total

Conversión, ejecución y servidor

  • La compilación solo requiere un compilador C11 y make
    • make check pasa 23 pruebas y omite 11 usando contenedores sintéticos sin modelo real
    • Con dos contenedores reales, el conjunto completo de pruebas es de 36
  • La conversión de K3 usa tal cual los 96 shards safetensors públicos de moonshotai/Kimi-K3
    • Toma alrededor de 4.7 horas en un M5 Pro con 3 procesos
    • Un encoder puro en PyTorch tarda 23.7 horas
    • Puede reanudarse por capa, así que tras una interrupción solo se reprocesa la capa en curso
    • El downloader soporta reanudación de archivos parciales, exponential backoff con jitter, verificación de Content-Length y registro del estado de shards completados
  • El CLI ofrece run, chat, eval, plan y más, y con --json produce salidas legibles por máquina para eval, tokenize, plan, info y bench
  • serve/ es un servidor HTTP compatible con OpenAI que llama a la API pública de C mediante ctypes
    • Ofrece /v1/chat/completions, /v1/completions, /v1/models y /health
    • Maneja streaming, definiciones y resultados de herramientas, typed call arguments, esquema JSON de respuestas, tool_choice, canal think, thinking_effort e imágenes
    • El renderer de prompts adaptó encoding_k3.py del release de K3, y si existe un directorio de pesos compara 38 conversaciones por segmento

Plataformas y limitaciones actuales

  • macOS arm64, Linux arm64 y Linux x86_64 registran 23 pass y 11 skip en las mismas pruebas no dependientes del modelo, y también pasan sanitizer y 400 casos de fuzzing
  • Windows x86_64 se valida con compilación cruzada vía MinGW-w64 para contenedores sintéticos, CLI y forward pass, pero no se ejecutó con contenedores reales del modelo
    • MSVC y Windows ARM64 no son compatibles
    • La omisión de la page cache en Windows solo se confirmó en el sistema de archivos de CI y no se validó bajo carga real con contenedores mayores que la RAM
  • El SIMD en x86 elige AVX-512 o AVX2 según CPUID, pero la ruta AVX-512 todavía no se ha ejecutado en un CPU con soporte real
  • El backend Metal es correcto, pero como la carga genera cientos de matvec dependientes pequeños, resulta 22% más lento que CPU y por eso está desactivado por defecto
  • La API aún no está fijada y la conversión automática de chat format por ahora solo soporta K3
    • Kimi-Linear no intenta adivinar la plantilla y se ejecuta en modo raw
  • No se planea introducir asignación no uniforme de bits por experto
    • El valor del tercer bit varía solo hasta 1.15x entre expertos de una misma capa y 1.01x entre capas, así que no hubo ganancia en una asignación óptima
    • La asignación basada en frecuencia de routing reduce almacenamiento, pero casi no reduce el I/O, que es el cuello de botella
  • La licencia es Apache 2.0

1 comentarios

 
GN⁺ 2 시간 전
Opiniones de Hacker News
  • Realmente genial. No es un proyecto que busque ser más práctico que los proveedores de nube ahora mismo, sino uno que muestra los límites de lo posible.
    Si las mejoras en la eficiencia de los modelos y el aumento del rendimiento del hardware local avanzan en conjunto, algún día los modelos locales de alta calidad podrían volverse económicamente viables.

  • Creo que 0.5 tokens por segundo no sirve ni para tareas largas. Preferiría gastar dinero en dos 4060 Ti de 16 GB y aplicar paralelismo de tensores.
    Dentro de 20 años quizá encaje con un robot lento de estilo cyberpunk que funcione con energía solar mientras corta el césped o limpia la banqueta, o con uno que pode en el jardín apenas siguiendo el ritmo de crecimiento de un bonsái.

    • Hoy casi no se puede usar, pero me alegra que proyectos así sigan mejorando, porque así eventualmente se llega a una versión práctica.
  • Dicen que es un desperdicio pagar por tokens y que el proveedor de inferencia pague la electricidad, pero no veo en qué se diferencia de comprar pepinos y que el agricultor pague el agua y el fertilizante. Espero que sea una lógica acomodada a posteriori por un LLM.
    La idea en sí es interesante y me gustaría probarla con modelos más pequeños. Si genera 0.5 tokens por segundo mientras lee varios GB por segundo desde el SSD, sigue siendo demasiado grande para una laptop de consumo común, pero podría resultar más práctico justamente para modelos de 250 a 500 GiB.

    • Si cultivas tus propios tomates, puedes conseguir tomates gratis. Quizá no alcance para hacer un BLT, pero como no son del supermercado, habrás salvado un poco al mundo /s
  • Suponiendo un consumo sostenido de 42 W y electricidad a 20 centavos por kWh, son unos 5 dólares por millón de tokens, sin contar otros costos como el hardware.

    • Un mes tiene unos 2.6 millones de segundos, y a 0.5 tokens por segundo se generan 1.3 millones de tokens al mes. Considerando los costos adicionales, tomar el costo mensual de operar el equipo como el costo por millón de tokens es una aproximación razonable.
    • Me pregunto cómo cambiaría el cálculo si hubiera generación solar.
  • El llama.cpp estándar también puede hacer mmap de GGUF, de modo que las partes que no caben en memoria quedan en disco, y la caché de páginas del kernel mantiene el tronco residente, la parte usada con frecuencia. Me pregunto qué ventaja tiene implementarlo por cuenta propia.

    • Hace unos días surgió la misma pregunta en un proyecto parecido, y dijeron que primero intentaron con mmap, luego lo implementaron directamente y quedó 10 veces más rápido.
      Es la misma razón por la que los motores de bases de datos implementan su propia caché. La paginación del kernel es genérica y bajo demanda, pero si conoces el patrón real de acceso puedes leer por adelantado y canalizar los datos necesarios.
    • A esta escala, usar un SSD como espacio de swap puede agotar fácilmente la resistencia de escritura acumulada en apenas unos meses. Me gustaría ver el total de escrituras acumuladas y las estadísticas de desgaste de SMART después de ejecutarlo más allá de una prueba corta.
      Para un modelo que cabe completo en RAM, era mejor ejecutar llama-server con --no-mmap. Claro que para cargar Kimi K3 completo y un contexto de 1 millón de tokens haría falta un servidor de 2 TB.
  • El README da una fuerte impresión de haber sido escrito por un LLM; me pregunto si la base de código también la escribió un LLM.

    • No quiero desestimarlo de forma superficial, pero la documentación se contradice sobre si realmente ejecuta el modelo con la precisión original. La cuantización a 3 bits que afirma podría ser interesante, pero K3 tiene alrededor de 115 GB solo en parámetros densos a precisión original, unos 25 GB de expertos dispersos activos por token, y además la caché KV, así que cuesta entender la afirmación de 2 segundos por token con 29 GB de RAM.
    • Escribí mucho software directamente e incluso creé un lenguaje de programación: https://github.com/marcobambini/gravity
      Ahora uso mis habilidades para coordinar LLMs y agentes, y así escribir mejor código mucho más rápido. Los desarrolladores tienen que elegir entre adaptarse a las nuevas tecnologías o quedarse atrás.
    • Ojalá los autores al menos hubieran leído ellos mismos el README generado por el LLM. Los LLMs tienen poca comprensión de la perspectiva del lector y asumen que los lectores externos también conocen todo el contexto del proyecto y el proceso de toma de decisiones.
      Incluye decisiones internas que son importantes para el usuario pero irrelevantes para quien ve el producto terminado, además de términos crípticos típicos de Claude. Reconozco que uso LLMs con frecuencia y que son muy útiles para escribir código complejo, pero la calidad de sus borradores de texto es pésima.
    • En la lista de contribuyentes aparece claude, así que ni siquiera hace falta adivinar. Si le confiaron a Claude hasta los commits, parece poco probable que hayan revisado el código personalmente.
    • En el README se siente con mucha fuerza el estilo característico de Claude. Igual que uno reconoce la forma de escribir de distintas personas, ahora siento que el estilo breve, entrecortado y con exceso de ritmo que Claude genera por defecto ya ocupa una categoría propia en mi cabeza.
  • Podría volverse valioso cuando la tecnología avance lo suficiente como para elegir con precisión el modelo adecuado para cada tarea. Puedo imaginar un futuro en el que, durante un proceso de exploración automática, se ejecute un modelo grande solo unos 30 minutos al día y el resto del tiempo se use un modelo pequeño.

    • No creo que ese futuro llegue. Incluso para los elementos del backlog solo sabes cuánto tomaron después de terminarlos; no hay forma de conocer de antemano la complejidad de una tarea sin ejecutarla de verdad.