Qwen3.8-27B en una sola RTX 3090: 262K de contexto a 65-80 tokens por segundo
Una receta para ejecutar un modelo denso de 27B con el contexto completo en una sola GPU de 24 GB: un fork afinado de llama.cpp, un cuantizado de 14,5 GB, caché Turbo3 y borradores MTP.
Un modelo denso de 27.000 millones de parámetros, la ventana de contexto completa de 262K, una sola GPU de consumo ya veterana y una velocidad de generación que se siente como hablar con una persona. Hasta hace poco, esa frase sonaba a marketing. Con Qwen3.8-27B y una compilación especializada de llama.cpp, ahora es una configuración reproducible en una sola RTX 3090.
Un poco de contexto sobre por qué importa. Qwen3.8-27B es un modelo sólido para el día a día, claramente por delante de la generación anterior, Qwen3.6. Pero ejecutarlo con buena calidad salía caro. La versión Q8, casi sin pérdidas, pide unos 28 GB de VRAM, así que no cabe en ninguna tarjeta de consumo por sí sola. Muchas configuraciones caseras juntaban dos RTX 3090 solo para servir un modelo así. La receta de abajo consigue una configuración mucho más ligera en una tarjeta normal de 24 GB lanzada en 2020.
Primero, las cifras
Medido en máquinas distintas, con un modelo y una GPU en cada una:
| GPU | Decode Speed | Prompt Prefill |
|----------------|-----------------|------------------|
| RTX 3090 | 65–80 tok/s | 1,000–1,300 t/s |
| RTX 3090 Ti | 70–100 tok/s | 1,200–1,700 t/s |
| RTX 5090 | 150–180 tok/s | 3,000–4,000 t/s |
Vuelve a mirar la primera fila: de 65 a 80 tokens por segundo en una sola RTX 3090. Es más rápido de lo que lee la mayoría de la gente y muy por encima de los cerca de 30 tok/s a partir de los cuales un chat empieza a sentirse natural. Y sale de una tarjeta que NVIDIA lanzó en 2020, moviendo un modelo denso de 27B con el contexto completo. La 3090 Ti llega a unos 100, y la 5090 se sitúa entre 150 y 180, lo que hace unos años habría pasado por rendimiento de centro de datos.
Eso supera con creces lo que daban las configuraciones locales anteriores. ¿Qué ha cambiado?
Tres pasos para reproducirlo
Paso 1: compilar el fork especializado de llama.cpp
Un fork de llama.cpp llamado llamAmpere apunta a las GPU Ampere y posteriores, y las exprime a fondo:
git clone -b main https://github.com/JakeATX/llamAmpere.git
cd llamAmpere
cmake -S . -B build-sm86 -DCMAKE_BUILD_TYPE=Release -DGGML_CUDA=ON -DGGML_CUDA_FA=ON \
-DCMAKE_CUDA_ARCHITECTURES=86 -DGGML_NATIVE=ON
cmake --build build-sm86 -j8 --target llama-server
Ese 86 es el código de arquitectura CUDA de las tarjetas de la serie RTX 30. En una generación más nueva, cámbialo: Ada (serie 40) usa 89 y Blackwell (serie 50) usa 120. El fork funciona en todas; solo cambia este flag de compilación.
Paso 2: descargar el modelo cuantizado a medida
La velocidad depende de una cuantización hecha a propósito llamada ATX-4-XS. Está publicada en Hugging Face como jakeatx/Qwen3.8-27B-ATX-IQ4_XS-M-GGUF y pesa 14,5 GB. Se puede descargar de dos maneras. Con la CLI de Hugging Face:
huggingface-cli download jakeatx/Qwen3.8-27B-ATX-IQ4_XS-M-GGUF \
--local-dir ~/models/qwen38-27b-atx
O con wget a secas, en la carpeta que prefieras:
mkdir -p ~/models/qwen38-27b-atx
wget -O ~/models/qwen38-27b-atx/Qwen3.8-ATX-4-XS.gguf \
"https://huggingface.co/jakeatx/Qwen3.8-27B-ATX-IQ4_XS-M-GGUF/resolve/main/Qwen3.8-ATX-4-XS.gguf"
Cambia las rutas si tus modelos están en otro sitio, por ejemplo en un disco dedicado.
Paso 3: arrancar el servidor
Lánzalo con este comando, adaptado a tus propios directorios:
CUDA_VISIBLE_DEVICES=0 GGML_Q8_TURBO3_MMA_FUSED=1 \
/home/andrewzhu/storage_1t_1/github_repos/llamAmpere/build-sm86/bin/llama-server \
-m /mnt/data_2t_3/ai_models_all/Qwen3.8-27B-ATX-IQ4_XS-M-GGUF/Qwen3.8-ATX-4-XS.gguf \
--alias Qwen3.8-27B-GGUF \
-c 262144 -b 4096 -ub 1024 -t 8 -tb 8 -ngl 99 -fa on -ctk q8_0 -ctv turbo3 \
--parallel 1 --jinja --fit off \
--cache-prompt --cache-ram 8192 --ctx-checkpoints 24 --checkpoint-min-step 10240 \
--spec-type draft-mtp --spec-draft-n-max 3 --spec-draft-p-min 0 \
--spec-draft-type-k q8_0 --spec-draft-type-v q8_0 \
--host 0.0.0.0 --port 8082 \
--spec-draft-vocab-map docs/mtp-vocab/atx_65536.txt
Hay dos detalles que, si se omiten, cuestan velocidad. Uno es la variable de entorno GGML_Q8_TURBO3_MMA_FUSED=1, que según las notas del propio fork aporta un 13 % y es la línea que todo el mundo olvida. El otro es el archivo vocab-map del final. Esa ruta, docs/mtp-vocab/atx_65536.txt, está dentro del repositorio del fork, que ya has clonado.
Por qué funciona
Aquí se suman cuatro ideas distintas. Ninguna es magia, y juntas muestran un trabajo de ingeniería cuidadoso.
1. Una compilación reescrita para una sola familia de chips
El llama.cpp estándar escribe sus kernels CUDA para que sean correctos en muchas generaciones de GPU. Este fork va en sentido contrario: reescribe las rutas críticas para una sola arquitectura y las afina hasta que no queda nada que exprimir.
Dos ejemplos. Qwen3.8-27B no es un transformer puro: 48 de sus capas guardan un estado recurrente Gated DeltaNet en lugar de atención. El fork rehízo esos kernels para que cada warp de la GPU se encargue de cuatro columnas de estado y no de una, lo que mantiene más llena la canalización del hardware. Eso dio entre un 5 y un 6 % tanto en prefill como en decode.
Las 16 capas restantes hacen atención de verdad. Sus claves se guardan comprimidas, y la ruta de descompresión anterior usaba solo un 10 % del ancho de banda de memoria, como beber con una pajita muy fina. La reescritura prepara los datos con copias asíncronas y corrige el patrón de lectura, lo que acelera hasta un 11 % la decodificación con contexto largo.
Los arreglos menos vistosos importaron igual. Dos correcciones en la asignación de memoria liberaron 2,8 GB de VRAM: un búfer se reservaba dos veces, y el drafter especulativo reservaba sus propios búferes de cómputo cuando podía compartir los del modelo principal. Esos 2,8 GB deciden si el contexto de 262K cabe en la tarjeta.
2. Una cuantización que reparte bien los bits
Un esquema de cuantización decide cuántos bits recibe cada peso. Uno ingenuo da a todos los tensores el mismo presupuesto, digamos 4 bits. Pero no a todos los tensores les afecta igual el redondeo.
La receta ATX-4-XS nació de medir qué roles de tensor sufren de verdad al comprimirse, como las proyecciones de atención y las cabezas de salida. Usa IQ4_XS como formato base y sube algunos roles concretos a Q5_0, Q6_K o Q8_0. El resultado es un archivo de 14,5 GB, más pequeño que una compilación Q4_K_M estándar del mismo modelo, que lee menos bytes de memoria en cada pasada y se mantiene cerca de la calidad completa para el trabajo diario.
Más pequeño significa más rápido porque generar token a token está limitado por el ancho de banda de memoria: cada token obliga a leer los pesos una vez desde la memoria de la GPU. Menos bytes por token, más tokens por segundo. Para que esto no se pagara en calidad hizo falta medir con cuidado qué bits conservar.
3. Turbo3: memoria a corto plazo compacta
Mientras genera, un modelo mantiene una caché KV, un registro de todo lo que ha leído y escrito para que cada token nuevo pueda mirar atrás. Con 262K tokens, esa caché es enorme. En formatos estándar se comería la mayor parte de la VRAM antes incluso de cargar los pesos.
Esta pila, heredada de la línea de trabajo TurboQuant+, guarda las claves de atención en q8_0 (casi sin pérdidas) y los valores rotados y comprimidos a unos 3 bits. De ahí el nombre Turbo3. La asimetría es deliberada: las claves funcionan como direcciones, y un error en ellas lo archiva todo en el sitio equivocado, mientras que los valores son contenido que admite una versión abreviada.
Una salvedad justa: esto no es fidelidad Q8 de punta a punta. Para programar, escribir y el uso diario con agentes no aparece ningún techo de calidad, pero si tu carga de trabajo exige una reproducción exacta bit a bit con temperatura 0, quédate con Q8 en dos tarjetas.
4. MTP y el mapa de vocabulario: adivinar por adelantado sale barato
La mayor ganancia viene de la decodificación especulativa con MTP (multi-token prediction). El modelo lleva una pequeña cabeza de borrador propia que propone los siguientes tokens, mientras el modelo grande valida esas propuestas en paralelo. En este fork la profundidad es 3: se adivinan tres tokens, los tres se verifican en una pasada y se conservan todos los aciertos.
Lo que cambió es la verificación. El llama.cpp anterior aceptaba un token de borrador solo si coincidía exactamente con la opción principal del modelo objetivo, algo estricto y derrochador. Esta pila usa en su lugar un muestreo por rechazo como es debido. Cada borrador se acepta con probabilidad min(1, p/q), donde p es la probabilidad que el modelo principal da al token y q la del drafter. Dicho llano: son dados limpios, con una distribución final demostrablemente idéntica a la de la generación normal, así que la salida llega antes con la misma calidad.
Queda el archivo de mapa. ¿Por qué el comando de arranque necesita un mapa de vocabulario?
Qwen3.8-27B tiene un vocabulario de casi 248.000 tokens. Cada paso de borrador multiplica el estado oculto por una enorme matriz de proyección que los cubre todos, de unos 1.152 × 248.320, es decir, unos 286 millones de multiplicaciones-acumulaciones por cada token propuesto. Sin embargo, el texto real apenas toca la mayor parte de ese vocabulario. Medido sobre salida real, una lista corta con los 65.536 tokens más frecuentes cubre el 99,59 % de las propuestas del drafter.
Así que el mapa recorta solo la proyección del drafter, y el modelo principal sigue eligiendo del vocabulario completo:
Full vocab draft head: 1,152 × 248,320 ≈ 286M MACs per draft token
Shortlisted (65K): 1,152 × 65,536 ≈ 75M MACs per draft token
Eso supone cerca de un 75 % menos de trabajo en la matriz más cara del drafter. Como el borrador se hace varias veces por cada token generado, fue la mayor aceleración individual de la versión v0.2, el salto de unos 65 a unos 75 tok/s. Sin el mapa, cada intento se paga entero.
Junta las cuatro capas: kernels reescritos, un reparto de bits más inteligente, memoria abreviada y comprimida y una anticipación barata. Una GPU de 2020 supera entonces lo que ofrecía el hardware especializado en 2023. La RTX 3090 no ha mejorado. Es la comunidad la que se ha vuelto muy buena exprimiéndola.
El panorama general
Piensa en lo que ha pasado. Un solo ingeniero, con ayuda de modelos de frontera, tardó unos días en conseguir que una GPU de consumo de 2020 sirviera un modelo abierto puntero a casi el triple de velocidad que la pila oficial, y luego publicó gratis los kernels, la cuantización y la receta.
Así está la IA local en 2026. Cada mes, algo que el trimestre pasado necesitaba dos tarjetas cabe en una. También cambia el debate sobre quién controla la IA. El hardware que ya está en casa de la gente puede ejecutar modelos modernos sin conexión, sin clave de API, sin factura por token y sin permiso de nadie. Las normas que encarecen la inferencia o limitan quién puede comprar capacidad de cómputo golpearían justo a este tipo de trabajo independiente.
Pienses lo que pienses de esos debates políticos, la lección práctica es sencilla. Los pesos están en tu propio disco, y el trabajo de eficiencia de la comunidad open source, entregado como kernels y commits en vez de anuncios, sigue abaratando el ejecutar tu propio modelo. El código está en el repositorio llamAmpere y el modelo es jakeatx/Qwen3.8-27B-ATX-IQ4_XS-M-GGUF.