Investigación

Medido, con los datos para comprobarlo.

El razonamiento anticipado no es exacto, así que se midió con respuestas que se pueden comprobar. Cada tabla de abajo tiene su script y su JSON en el repositorio, y el diario de investigación guarda las notas de trabajo, las más recientes primero.

Método

Problemas de enunciado con respuesta numérica conocida, tecleados en italiano en tiempo real: de 5 a 8 caracteres por segundo, algunas pausas naturales, Enter justo después del último carácter, sin releer. El script es research/thinking_ahead.py; teclea cada problema con y sin razonamiento anticipado y registra la espera hasta la primera palabra de la respuesta, los tokens de razonamiento en total y los que quedan tras Enter, y si la respuesta es correcta.

Los modelos son Qwen3 Q4_K_M en modo thinking sobre llama.cpp (b11747). La máquina de referencia es una RTX 2060 con 6 GB de VRAM (i5-10400, 16 GB DDR4, Windows 11): Qwen3-4B cabe en la VRAM a unos 83 tok/s, Qwen3-14B no (38% en la GPU, unos 5 tok/s). La segunda máquina es un MacBook Pro M2 Pro, 16 GB, con Metal. Dos ejecuciones de los mismos 24 problemas difieren hasta en un segundo en la media: compara filas medidas una tras otra.

Resultados

Modelo · máquinaProblemasCorrectasEspera media, sinEspera media, MAFDETMediana, sin → MAFDET
Qwen3-4B
RTX 2060 · 6 GB
2424/24 con y sin12.2 s3.2 s10.7 s → 2.9 s
Qwen3-14B
RTX 2060 · 6 GB
66/6 con y sin108 s47 s—
Qwen3-4B
MacBook Pro M2 Pro · 16 GB
2424/24 con y sin18.1 s5.6 s16.7 s → 4.1 s
Qwen3-14B
MacBook Pro M2 Pro · 16 GB
66/6 con y sin32.7 s12.1 s26.5 s → 11.7 s

Razonamiento anticipado, Qwen3-4B en la RTX 2060, 24 problemas (research/thinking_ahead.py, datos thinking_ahead_4b.json):

Sin razonamiento anticipadomafdet strike
Respuestas correctas24/2424/24
Mediana de la espera hasta la primera palabra10.7 s2.9 s
Espera media12.2 s3.2 s
Más rápidoen 24 de 24 problemas
Razonamiento en total944 tokens662 tokens
Razonamiento pendiente tras Enter944 tokens244 tokens

La misma precisión, menos razonamiento en total (el material reunido mientras se escribe ahorra al modelo empezar de nuevo), y casi dos tercios de él hechos antes de Enter. El marco de las notas importa: un marco genérico dio 22/24 y una mediana de 4.4 s; sin marco, 22/24, 6.9 s y un 70% más de razonamiento. Con el marco en lista, la línea de ejemplo y un sesgo de logits contra palabras como user, incomplete, typing durante el razonamiento anticipado, la proporción de frases de las notas sobre el mensaje en sí en vez de sobre su contenido pasó del 86% al 17-26%.

Respuesta exacta por adelantado

Qwen3-4B, sin razonamiento, pausa antes de Enter con el texto sin cambios: la respuesta misma se escribe por adelantado, y esa parte es exacta (con decodificación greedy, idéntica token a token a la que empieza tras Enter; comprobado).

RespuestaEscrita antes de EnterRespuesta completa en pantalla tras Enter, strikeSin strike
300 tokens2001.2 s3.5 s
168 tokens168 (toda)instantánea1.9 s

Modelos más grandes

Lo que el modelo puede hacer antes de Enter está limitado por el tiempo de escritura × su velocidad de escritura:

Modelo¿Cabe en 6 GB?EscribeRazonamiento escrito mientras se teclea un mensaje de 30 s
Qwen3-4Bsí83 tok/sla mayor parte
Qwen3-8Bno, en parte en la CPU13 a 16 tok/s130 a 280 tokens
Qwen3-14Bno, en parte en la CPU5 tok/sunos 160 tokens

Aun así, en el 14B (6 problemas, 6/6 correctas con y sin) el razonamiento anticipado reduce a la mitad la espera media tras Enter: 108 s → 47 s, con 164 tokens de razonamiento escritos antes de Enter de media. Las ejecuciones sueltas varían mucho (el mismo problema tardó 106 s una vez y 154 s otra), así que 6 problemas dan el orden de magnitud. La lectura anticipada gana más cuanto más grande es el modelo: el 14B lee un documento pegado de 3,000 tokens en unos 10 s, todo ello oculto mientras escribes.

Adivinar el final (--branches, experimental). El razonamiento pendiente tras Enter trata sobre todo del final del mensaje, que llega el último. Con --branches 1 el modelo también adivina cómo terminarás y razona sobre la suposición en un slot propio. Los mismos 24 problemas, dos ejecuciones cada uno: 48/48 correctas, espera media 4.17 s → 3.51 s, décimo más lento 7.9 s → 5.3 s, 14 de 48 mensajes adivinados exactamente. Una ganancia modesta, sobre todo en las respuestas más lentas, con 24 problemas aún no significativa (test de signos p = 0.15). En el 14B ninguna rama llegó a empezar a razonar antes de Enter: en la app solo se da una rama a los modelos que caben en la VRAM.

Un modelo pequeño reuniendo material para uno grande (--gatherer, experimental). Un Qwen3-0.6B rápido, también ajustado para ello, escribiendo material mientras tecleas para que el 14B lo lea al pulsar Enter. En la RTX 2060 no supera al 14B razonando por adelantado por sí solo: 47 s frente a 60 s sin entrenar y 79-86 s ajustado; incluso un material ideal escrito a mano da 62 s, o 49 s cuando se presenta como razonamiento propio del modelo. El 14B lo lee y luego rehace los cálculos. Las preguntas abiertas para quien quiera llevar esto más lejos están en el README.

En un Mac

MacBook Pro M2 Pro, 16 GB, macOS 26.2, llama.cpp con Metal; los mismos scripts y problemas.

M2 ProSin razonamiento anticipadomafdet strike
Qwen3-4B, 24 problemas: correctas24/2424/24
Mediana de la espera16.7 s4.1 s
Espera media18.1 s5.6 s
Razonamiento en total / pendiente tras Enter966 / 966773 / 248
Qwen3-14B, 6 problemas: correctas6/66/6
Mediana de la espera26.5 s11.7 s
Espera media32.7 s12.1 s

El 4B escribe a 54 tok/s en el M2 Pro (83-87 en la RTX 2060), así que las dos esperas son más largas que en el PC, y el razonamiento anticipado les quita más o menos la misma proporción. El 14B es donde el Mac se diferencia: Metal puede usar 12 GB de la memoria unificada, así que el modelo entero está en la GPU y escribe a 18 tok/s. Durante las ejecuciones el Mac alcanzó presión térmica Heavy durante unos minutos. Datos: thinking_ahead_4b_m2pro.json, thinking_ahead_4b_m2pro_fixed.json, thinking_ahead_14b_m2pro.json.

Probado, y por qué no

  • --recycle (respuestas a versiones anteriores del mensaje como borradores n-gram): +4% de velocidad de decode con escritura natural, +20% en código, primer token ligeramente más tarde.
  • --draft (Qwen3-0.6B redactando para el 14B): en la GPU le quita VRAM al 14B, que entonces corre más capas en la CPU (4.8 → 3.5 tok/s); en la CPU gana un 8% con borradores de 4 tokens y reduce a la mitad la velocidad de lectura.
  • El razonamiento anticipado como borrador para la decodificación especulativa tras Enter: no es más rápido en el 4B (73 tok/s en ambos casos) y es más lento en el 14B (5.0 → 3.1 tok/s), porque las capas en la CPU calculan cada token del borrador y solo el 11% de los tokens del borrador eran correctos. Script: research/notes_as_draft.py.
  • IQ4_XS en vez de Q4_K_M en el 4B (RTX 4070 SUPER): un 4% más rápido, una respuesta peor de 28. No vale la pena en el 4B; en el 14B, donde es un 31% más rápido con las mismas respuestas, está por decidir.

Lección clave: en un modelo repartido entre GPU y CPU, las capas de la CPU calculan cada token que reciben. Cualquier cosa que procese varios tokens a la vez le cuesta al 14B casi proporcionalmente. Para acelerar el 14B, quítale trabajo a la CPU.

Se busca ayuda: Radeon

MAFDET funciona en tarjetas Radeon con la build Vulkan de llama.cpp, pero nadie lo ha medido en una todavía. La ruta Vulkan en sí está comprobada, en la RTX 2060 (Qwen3-4B lee 2,103 tokens/s y escribe 83, más o menos como con CUDA). Si tienes una tarjeta dedicada, RX 5000 o posterior, 8 GB o más es lo ideal, media hora bastaría para llenar este hueco:

  1. Instala MAFDET y ábrelo una vez: debería encontrar tu tarjeta, instalar llama.cpp Vulkan y descargar Qwen3-4B. mafdet doctor muestra lo que ha encontrado.
  2. En la app, Modelos, Mide Qwen3-4B.
  3. Desde la carpeta de MAFDET, con su entorno activo: python research/thinking_ahead.py radeon_4b.json. Unos 20 minutos; deja la máquina sin hacer nada más mientras tanto.
  4. Abre un issue con la salida de mafdet doctor, los números de Medir y radeon_4b.json.