- Zinc es un motor de inferencia LLM en Zig que aprovecha GPU AMD RDNA3/RDNA4 y Apple Silicon sin depender de ROCm, CUDA ni Python.
- Utiliza Vulkan en Linux y Metal en macOS con shaders afinados para cada arquitectura y soporte validado para modelos GGUF cuantizados.
- Ofrece CLI, servidor HTTP con API compatible con OpenAI y chat web integrado en un solo binario sencillo de compilar con Zig.
- El proyecto está en desarrollo activo, con buenas cifras de rendimiento y una hoja de ruta centrada en batching, compresión KV y mayor eficiencia.

Zinc es un motor de inferencia local para modelos de lenguaje grande (LLM) pensado para exprimir al máximo las GPU de consumo de AMD (RDNA3 y RDNA4) y los chips Apple Silicon, usando Zig como lenguaje y Vulkan/Metal como backends gráficos. Si tienes una gráfica moderna y te frustra no poder usarla bien con vLLM, ROCm o soluciones poco optimizadas, este proyecto viene precisamente a cubrir ese hueco.
El objetivo de Zinc es muy claro: ofrecer una forma sencilla, rápida y sin dependencias pesadas de ejecutar modelos en formato GGUF a nivel local, con una sola compilación, un único binario y un servidor compatible con la API de OpenAI y con una interfaz de chat integrada en el navegador. Todo ello con shaders hechos a mano para cada plataforma, un diseño de bajo nivel y una experiencia de uso pensada para desarrolladores y usuarios avanzados.
Qué es Zinc (Zig inference engine) y qué problema resuelve
Zinc es un motor de inferencia LLM escrito principalmente en Zig y diseñado desde cero para aprovechar a fondo el hardware de dos familias de GPU muy extendidas pero tradicionalmente mal servidas por el ecosistema de IA: las GPU AMD de consumo basadas en RDNA3/RDNA4 y los SoC Apple Silicon (M1, M2, M3, M4, M5). En vez de apoyarse en ROCm, CUDA o MLX, se basa en Vulkan 1.3 en Linux y Metal en macOS.
El origen del proyecto nace de una queja recurrente en la comunidad: quien tiene una gráfica AMD potente se encuentra con que ROCm no soporta bien las tarjetas de consumo, vLLM directamente no funciona sin ROCm y la ruta Vulkan de llama.cpp trata a la GPU como un actor secundario, con shaders genéricos, sin afinado específico para la arquitectura y sin una historia de servidor sólida.
La premisa de Zinc es que el hardware ya está listo: las tarjetas RDNA3 y RDNA4 tienen ancho de banda de memoria, cómputo y VRAM de sobra para mover modelos grandes, y los chips Apple Silicon cuentan con memoria unificada y potentes unidades de cálculo. El cuello de botella real está en el software, así que se ha construido un motor específico para esas plataformas, con un enfoque de sistemas de muy bajo nivel.
En la práctica, Zinc es capaz hoy de cargar modelos GGUF grandes (en torno a 21 GB de pesos en VRAM para un modelo de 35B parámetros), construir un grafo de cómputo con cientos de nodos (por ejemplo para un transformer híbrido con MoE y capas SSM) y generar texto coherente a velocidades competitivas, especialmente en hardware RDNA4 afinado.
Por qué se ha elegido Zig para construir Zinc
Zig encaja muy bien con el tipo de trabajo que requiere un motor de inferencia GPU centrado en Vulkan y Metal: llamadas intensivas a la API gráfica, gestión manual de memoria de GPU, grabación de command buffers y un pipeline de construcción de shaders integrado. Es código de sistemas puro y duro, y Zig ofrece un conjunto de herramientas muy ajustado a esa realidad.
Un punto clave es @cImport, que permite acceder directamente al ABI C de Vulkan sin generar bindings complejos ni capas adicionales. Esto facilita llamar a las funciones de la API de bajo nivel exactamente como están definidas, reduciendo fricción y sobrecarga al interactuar con el driver y el runtime gráfico.
El uso de comptime en Zig resulta muy útil para generar tablas de despacho por tipo de cuantización y para especializar rutas de código en tiempo de compilación, lo que se traduce en menos branching en tiempo de ejecución y en una selección más eficiente de kernels y formatos como Q4_K, Q5_K, Q6_K, Q8_0 o F16 según el modelo GGUF que se cargue.
La gestión de errores y recursos con errdefer ayuda a mantener bajo control la limpieza de recursos de GPU: buffers, imágenes, descriptores y otros objetos Vulkan/Metal se liberan correctamente incluso cuando hay errores intermedios, evitando fugas de VRAM y estados inconsistentes tras fallos en mitad de la inicialización o del decode loop.
El propio sistema de build de Zig simplifica mucho la integración de compilación de shaders: la orden zig build puede encadenar pasos para invocar glslc en Linux, dejar los SPIR-V ya compilados en zig-out/share/zinc/shaders/ y producir en zig-out/bin/zinc un binario único que lo agrupa todo. En macOS, los shaders Metal (MSL) se compilan en tiempo de ejecución.
Arquitectura general: Vulkan en AMD y Metal en Apple Silicon
Zinc está diseñado con dos rutas de ejecución diferenciadas, una para Linux con GPU AMD mediante Vulkan 1.3 y otra para macOS con Apple Silicon mediante Metal, aunque desde el punto de vista del usuario la experiencia es prácticamente la misma: construir el binario, elegir un modelo GGUF validado y lanzar inferencia vía CLI, servidor HTTP o interfaz de chat web.
En la ruta AMD se aprovechan al máximo las capacidades de RDNA3 y RDNA4: se utilizan shaders de cómputo escritos a mano en GLSL, con wave64, cooperative matrix y estrategias de tiling específicas de la arquitectura, ejecutados sobre Vulkan. No se trata de un backend genérico que “también funciona en AMD”, sino de kernels expresamente ajustados para sacar partido del hardware.
En Apple Silicon, Zinc usa shaders nativos en Metal (MSL) con operaciones simdgroup, aprovechando la memoria unificada y el acceso cero-copia (zero-copy mmap) para cargar los modelos directamente sin pasos intermedios de copia costosos. Esto encaja muy bien con la filosofía de los SoC de Apple, donde CPU y GPU comparten el mismo espacio de memoria.
La elección del backend se hace automáticamente en tiempo de compilación: Zig detecta si se está construyendo en un entorno Linux con soporte Vulkan o en macOS con Metal y activa la ruta correspondiente. Desde el punto de vista del comando de build, el usuario simplemente ejecuta zig build -Doptimize=ReleaseFast y obtiene un binario listo para su plataforma.
Este diseño evita depender de pilas de drivers específicas como ROCm o MLX, así como de runtimes como CUDA o Python. Zinc se plantea como “un solo binario, sin stack pesado de ML”, algo especialmente atractivo para quien quiere montar un servidor local de LLM en una máquina de escritorio o portátil sin entrar en instalaciones complejas.
Plataformas, GPU y modelos soportados
Actualmente Zinc se centra en dos grandes entornos: Linux con GPU AMD RDNA3/RDNA4 vía Vulkan 1.3, y macOS con Apple Silicon desde M1 hasta M5, vía Metal. Esto cubre tanto tarjetas dedicadas de escritorio como tarjetas orientadas a IA (por ejemplo Radeon AI PRO) y los chips integrados en portátiles y sobremesas de Apple.
En Linux, la compatibilidad se ha validado en tarjetas como la AMD Radeon AI PRO R9700 (RDNA4, 32 GB) y tarjetas RDNA3 como la RX 7900 XTX. Para RDNA4, se recomienda activar la optimización de cooperative matrix mediante la variable de entorno RADV_PERFTEST=coop_matrix antes de ejecutar Zinc, ya que esto habilita rutas de cómputo más eficientes en el driver RADV.
En macOS, Zinc funciona sobre Apple Silicon desde los primeros M1 hasta generaciones recientes como M4 o posteriores, usando Metal como backend y shaders MSL específicamente escritos. Se ha probado, por ejemplo, en un M1 Pro con 32 GB de memoria unificada, suficiente para albergar modelos de varios miles de millones de parámetros y ciertas variantes de 35B con requisitos concretos de memoria.
En cuanto a modelos, Zinc se limita a un conjunto de GGUF muy concreto que se han validado extremo a extremo, en lugar de listar un catálogo teórico enorme. Entre ellos se encuentran variantes de Qwen3.5 de 2B y 35B parámetros, con cuantizaciones como Q4_K_M o Q4_K_XL, pensadas para equilibrar consumo de VRAM y rendimiento en inferencia.
Los formatos de cuantización compatibles incluyen Q4_K, Q5_K, Q6_K, Q8_0 y F16, lo que permite ajustar la calidad y la velocidad según el hardware disponible. En los benchmarks actuales, por ejemplo, el modelo Qwen3.5 2B Q4_K_M alcanza del orden de 27 tok/s en RDNA4 y unos 17 tok/s en Apple Silicon en decodificación de un solo stream.
Rendimiento actual y estado del proyecto
Zinc es todavía software experimental, en pleno desarrollo activo, pero ya cuenta con números de rendimiento respetables y un pipeline estable para inferencia en CLI y servidor HTTP. En un entorno de prueba con Radeon AI PRO R9700 (RDNA4, 32 GB, 576 GB/s), se han medido velocidades de alrededor de 38 tok/s en el modelo Qwen3.5 35B-A3B UD cuantizado en Q4_K_XL.
En pruebas de decodificación sencilla por línea de comandos, un caso típico es lanzar un prompt corto como «The capital of France is» y generar 128 tokens. En esas condiciones, se han visto cifras cercanas a 37,95 tok/s con unos 26,3 ms/tok en el modelo de 35B, y alrededor de 26,71 tok/s (37,4 ms/tok) en el modelo de 2B Q4_K_M en el mismo nodo RDNA4.
Llama la atención que el modelo de 35B pueda ir más rápido que el de 2B en ese hardware, lo cual indica que el cuello de botella no está simplemente en el número de parámetros, sino en la forma del grafo, el tipo de kernels usados y la eficiencia de la ruta de decode. El motor está alcanzando unos 112,5 GB/s de ancho de banda modelado para la ruta de token completo, alrededor del 19,5% del pico teórico del chip.
Esta aparente “infrautilización” de la memoria no es un problema en sí, ya que un único stream de decodificación no está pensado para saturar por completo el ancho de banda DRAM. El tiempo restante se va en kernels medianos y pequeños, y en la profundidad del grafo de cómputo. Para mejorar la utilización global, la palanca adecuada no es pedir a un solo stream que lo haga todo, sino implementar batching y concurrencia.
En comparación con otros motores como llama.cpp, el baseline actual de Zinc en RDNA4 para el modelo de 35B y decodificación básica se acerca a 40 tok/s, mientras que llama.cpp puede estar por encima de 100 tok/s en el mismo nodo y modelo. La hoja de ruta de Zinc pasa por cerrar esa brecha optimizando kernels calientes, reduciendo sobrecostes de Vulkan y mejorando la ruta de chat razonado (/v1/chat/completions) para acercarla al rendimiento de la ruta de decode puro.
Componentes internos y shaders afinados
El motor de Zinc se compone de varios bloques fundamentales ya completados: infraestructura Vulkan, parser GGUF y cargador de modelos, detección de GPU RDNA3/RDNA4, tokenizador BPE nativo (a partir de los metadatos GGUF), un conjunto de 16 shaders de cómputo GLSL, constructores de grafos de cómputo y arquitecturas, y el bucle de forward pass para la decodificación.
Los shaders en AMD están escritos específicamente para RDNA, usando wave64, cooperative matrix y esquemas de tiling ajustados a la jerarquía de memoria y a las unidades de cómputo de la arquitectura. Esto contrasta con soluciones genéricas donde el mismo shader sirve para todo y el rendimiento queda lejos del potencial de la tarjeta.
En Apple Silicon, las rutas están apoyadas en kernels MSL nativos que explotan las simdgroup operations y el acceso directo a modelos mapeados en memoria unificada, minimizando copias y sacando partido a la naturaleza integrada del chip. La optimización de esta ruta va un poco por detrás de la de RDNA4, pero está en progreso activo.
El grafo de cómputo que Zinc construye para un modelo complejo como Qwen3.5 35B-A3B-UD puede alcanzar más de 700 nodos, incluyendo capas MoE (Mixture of Experts), SSM y proyección de vocabulario. Todo este grafo se está moviendo hacia una estrategia donde la decodificación se graba como un único comando Vulkan por token, reduciendo los 120 viajes GPU-CPU por token que actualmente penalizan la velocidad.
Además del núcleo de inferencia, Zinc incluye un servidor HTTP integrado con API compatible con OpenAI bajo /v1, así como una interfaz de chat en el navegador servida desde /. La API soporta streaming de tokens, y existe un endpoint de salud en /health para integraciones con orquestadores y sistemas de monitorización.
Instalación de dependencias y compilación de Zinc
Para usar Zinc necesitas muy pocas herramientas externas, especialmente si estás en macOS con Apple Silicon. En ese entorno basta con instalar Zig (versión 0.15.2 o superior) y las herramientas de línea de comandos de Xcode mediante xcode-select –install. No hace falta Vulkan, glslc, Python ni MLX, porque toda la ruta se apoya en Metal y en el build system de Zig.
En Linux con GPU AMD la preparación es igual de directa: se recomienda actualizar los paquetes con apt update e instalar libvulkan-dev, vulkan-tools y glslc, además de git para clonar el repositorio. Zig 0.15.2+ debe descargarse desde la web oficial y añadirse al PATH para poder ejecutar zig build sin problemas.
Una vez instaladas las dependencias, el flujo de compilación es idéntico en ambas plataformas: se clona el repositorio oficial de GitHub con git clone https://github.com/zolotukhin/zinc.git, se entra al directorio y se lanza zig build -Doptimize=ReleaseFast. La opción ReleaseFast es importante para obtener un binario optimizado y evitar medidas de rendimiento engañosas.
El binario resultante se guarda en ./zig-out/bin/zinc. En Linux, el proceso de build compila también los shaders GLSL a SPIR-V y los deja en zig-out/share/zinc/shaders/. En macOS, en cambio, la compilación de shaders Metal se realiza en tiempo de ejecución a partir del código MSL incluido en el proyecto.
Conviene tener en cuenta un detalle relevante en Linux RDNA4: algunas versiones nuevas de glslc pueden introducir regresiones de rendimiento importantes al compilar los shaders. La recomendación del proyecto es usar la versión de glslc que viene en los repositorios del sistema en lugar de versiones más recientes obtenidas por otras vías.
Comprobación previa y primeros pasos con Zinc
Antes de lanzar cualquier prompt, se aconseja ejecutar un chequeo previo con el comando ./zig-out/bin/zinc –check. Esta orden verifica que el entorno del host, la GPU y los assets necesarios están en orden, y que no faltan shaders, capacidades Vulkan/Metal o metadatos de modelos.
En máquinas con RDNA4 es especialmente útil exportar la variable RADV_PERFTEST=coop_matrix antes del chequeo y de las sesiones de inferencia, y luego volver a llamar a ./zig-out/bin/zinc –check. El objetivo es confirmar que la GPU se ha detectado correctamente, que las optimizaciones de cooperative matrix están activas y que no surgen advertencias críticas.
Si el chequeo termina mostrando READY [OK], es señal de que el entorno está en estado razonable para probar inferencia. Si aparecen avisos, es recomendable resolverlos primero (drivers, versiones de Vulkan, shaders sin compilar, falta de VRAM para el modelo escogido, etc.) antes de juzgar el rendimiento o estabilidad del motor.
En el chequeo se validan también aspectos como el descubrimiento de dispositivos Vulkan, la selección de la GPU activa, la compatibilidad de los modelos gestionados cuando se pasa –model-id, el metadata de los GGUF y una estimación de si el modelo cabe o no en la VRAM disponible en la GPU seleccionada.
Superada esa fase, el flujo recomendado es muy sencillo: listar el catálogo de modelos aptos para la máquina, descargar uno validado para tu perfil de GPU y realizar una primera inferencia por CLI con un prompt corto. Esto permite verificar que el pipeline completo (tokenización, forward pass, salida de texto) funciona de manera coherente.
Catálogo de modelos, descarga y gestión
Zinc incorpora un sistema de modelos gestionados que detecta el perfil de GPU (por ejemplo amd-rdna4-32gb o apple-silicon) y muestra cuáles de los modelos validados encajan mejor con esa configuración de memoria y capacidades. El comando ./zig-out/bin/zinc model list sirve para navegar este catálogo.
Para descargar un modelo, se utiliza la orden model pull, por ejemplo ./zig-out/bin/zinc model pull qwen35-2b-q4k-m. Esto baja el archivo GGUF correspondiente al modelo Qwen3.5 2B con cuantización Q4_K_M y lo guarda en una caché local, verificando además el hash SHA-256 para asegurar la integridad de la descarga.
Una vez descargado, puedes establecer un modelo por defecto para futuras ejecuciones con ./zig-out/bin/zinc model use qwen35-2b-q4k-m, y comprobar cuál es el modelo activo en ese momento con ./zig-out/bin/zinc model active. De esta forma, muchas invocaciones posteriores no necesitan especificar –model-id explícitamente.
Cuando ya no necesites un modelo, es posible liberarlo de la caché con ./zig-out/bin/zinc model rm qwen35-2b-q4k-m, lo que ayuda a gestionar el espacio en disco si experimentas con varias versiones de cuantización o con modelos alternativos.
El catálogo intencionadamente se mantiene estrecho, centrado en modelos que el equipo del proyecto ha validado extremo a extremo, en lugar de prometer compatibilidad teórica con cientos de variantes GGUF. Para detalles más finos sobre workflows de modelos y opciones de caché, se remite a la documentación web específica de Zinc.
Inferencia por CLI, servidor HTTP y chat web
La forma más directa de probar Zinc es con la CLI. Una vez compilado el binario, descargado un modelo y superado el chequeo, puedes lanzar una primera prueba sencilla con algo como ./zig-out/bin/zinc –model-id qwen35-2b-q4k-m –prompt «The capital of France is». En Linux RDNA4, recuerda tener export RADV_PERFTEST=coop_matrix activo para aprovechar cooperative matrix.
Si todo está bien configurado, los logs deberían mostrar mensajes del cargador de modelos, la finalización del prefill y el número de tokens generados junto con la velocidad en tok/s, terminando con un texto de salida coherente, típicamente con la palabra “Paris” en el ejemplo anterior. Ver esa secuencia indica que la ruta principal de inferencia está operativa.
Además del modo CLI puro, Zinc integra un modo servidor accesible con ./zig-out/bin/zinc chat, que arranca un servidor HTTP (por defecto en el puerto 9090) y abre en el navegador la interfaz de chat incorporada. Desde ella puedes interactuar con el modelo de manera similar a un chat online, incluyendo soporte para modos de “razonamiento” más largos.
El servidor también se puede lanzar manualmente con ./zig-out/bin/zinc –model-id qwen35-2b-q4k-m -p 8080, de modo que puedas elegir el puerto que más te convenga. Luego basta con abrir http://localhost:8080/ en el navegador para acceder a la misma interfaz de chat integrada en el binario.
La API HTTP que expone Zinc es compatible con OpenAI bajo la ruta /v1, lo que permite apuntar clientes o SDKs que ya trabajan con la API de OpenAI directamente contra tu instancia de Zinc. También se incluye un endpoint /health pensado para chequeos de estado en despliegues de producción o en entornos orquestados.
Limitaciones actuales y hoja de ruta
Aunque Zinc ya es funcional, el proyecto declara abiertamente que sigue en una fase experimental y que algunas partes están en plena evolución. El modo CLI es hoy el camino más pulido para empezar; el servidor, la cobertura de modelos y la optimización fina de rendimiento se están puliendo con iteraciones frecuentes.
Hay algunas limitaciones reconocidas: el listado de modelos soportados se mantiene a propósito estrecho; la ruta de Apple Silicon todavía está en fase de tuning para acercarse a la eficiencia de RDNA4; y la implementación de batching continuo y multiproceso para servir a múltiples clientes a la vez está en la hoja de ruta pero no completamente cerrada.
El equipo de desarrollo está trabajando en varias líneas clave para pasar de “decode bruto por encima de 30 tok/s” a soportar cargas de trabajo de razonamiento largas manteniendo esa cifra y mejorando la utilización agregada de la GPU. Esto incluye cerrar la brecha entre /v1/completions y /v1/chat/completions, donde plantillas de chat y tiempos de primer token (TTFT) añaden sobrecarga adicional.
Otra área en la que se está iterando es la reducción del churn de descriptores en el camino caliente de Vulkan: la idea es reutilizar bindings y minimizar el trabajo por token en el bucle de decodificación, de modo que el tiempo de CPU y la latencia por operación Vulkan se mantengan lo más bajos posible.
Entre las fases avanzadas previstas se incluye TurboQuant KV compression, una técnica de compresión del estado KV (key-value) que puede ayudar a reducir el consumo de memoria y mejorar la velocidad en secuencias largas, así como la implementación de batching continuo para incrementar la tasa de tokens por segundo a nivel agregado con múltiples flujos simultáneos.
Quienes quieran profundizar más en el código disponen de una base relativamente manejable: unas 5.000 líneas de Zig y unas 2.000 de GLSL, junto con shaders MSL para Apple, herramientas de perfilado (–profile, aún en ajuste para que no distorsione mediciones) y una guía de desarrollo detallada en la documentación web.
En conjunto, Zinc dibuja un panorama interesante para cualquiera que tenga una GPU AMD moderna o un equipo Apple Silicon y quiera sacar verdadero partido de su hardware para LLM locales, sin pasar por ROCm, CUDA ni runtimes pesados de Python. Su combinación de Zig, Vulkan y Metal, junto con un set de shaders ajustados a cada arquitectura, lo convierten en una opción a seguir de cerca si te interesa montar un entorno de inferencia eficiente en tu propia máquina, ya sea para experimentar, para servir una API compatible con OpenAI o para entender a fondo cómo se construye un motor de inferencia de bajo nivel.
Redactor apasionado del mundo de los bytes y la tecnología en general. Me encanta compartir mis conocimientos a través de la escritura, y eso es lo que haré en este blog, mostrarte todo lo más interesante sobre gadgets, software, hardware, tendencias tecnológicas, y más. Mi objetivo es ayudarte a navegar por el mundo digital de forma sencilla y entretenida.