DEV Community

Cover image for Gated DeltaNet: la memoria lineal de Qwen3.5
lu1tr0n
lu1tr0n

Posted on Originally published at elsolitario.org

Gated DeltaNet: la memoria lineal de Qwen3.5

Un modelo de lenguaje de 4.000 millones de parámetros corre un procesador RISC-V completo sin ningún plugin ni sandbox externo. Así funciona Qwenputer, el experimento del investigador Divyansh Agrawal sobre Qwen3.5. La pieza que lo hace posible es Gated DeltaNet, la capa de atención lineal que ya usa el modelo original, pero reconfigurada para funcionar como memoria RAM exacta y direccionable.

El experimento es una curiosidad, pero la capa que explota es real y corre en producción: Alibaba la usa en Qwen3-Next y Qwen3.5. Esa capa de atención lineal explica cómo estos modelos manejan contextos largos sin que el costo por token crezca con cada mensaje nuevo.

TL;DR

  • Fijar la compuerta en 1.0 y usar claves one-hot convierte el estado de la atención lineal en una fila de RAM exacta.- Qwenputer compila un CPU RISC-V RV32IM en 11 de las 32 capas de Qwen3.5, sin entrenamiento adicional.- El estado de cada cabeza de atención lineal pesa igual sin importar cuántos tokens lleve la conversación, a diferencia del KV-cache.- Por defecto, Qwen3.5 usa una compuerta menor a 1.0, así que la memoria se desvanece en vez de grabarse para siempre.- La regla delta de Schlag, Irie y Schmidhuber (2021) ya describía esta memoria asociativa; Qwenputer la vuelve exacta y direccionable.

¿Qué es Gated DeltaNet?

Gated DeltaNet es una capa de atención lineal que Qwen3-Next y Qwen3.5 usan en 3 de cada 4 bloques de atención, en vez de revisar todo el historial como la atención estándar. Mantiene una matriz de estado por cabeza que se actualiza token a token con una compuerta de olvido y una regla de escritura, la regla delta.

La idea no es nueva. En 2021, Schlag, Irie y Schmidhuber mostraron que la atención lineal con la regla delta funciona como una memoria asociativa, o "pesos rápidos". Qwenputer toma esa misma matemática y la empuja a un extremo: compuerta en 1.0, fuerza de escritura en 1.0 y claves codificadas como un solo 1 entre ceros (one-hot). El resultado deja de ser una memoria difusa y se convierte en RAM direccionable, fila por fila.

Por qué importa esta memoria direccionable

La atención estándar de un transformer guarda cada token en una caché de clave-valor que crece sin límite. Cuanto más larga la conversación, más memoria y más cómputo necesita cada paso nuevo. La atención lineal con compuerta resuelve ese problema con un truco distinto: comprime todo el pasado en una matriz de tamaño fijo por cabeza, así que el costo por token no sube con el largo del contexto.

El problema es que, en su forma estándar, esa compresión es con pérdida. La compuerta por defecto mezcla valores viejos y nuevos, así que no hay forma de leer un dato exacto de vuelta. Qwenputer demuestra que, si se ajustan la compuerta y la fuerza de escritura a los extremos correctos, la misma capa puede guardar valores exactos sin perder la ventaja de tamaño fijo. Eso es lo que permite simular registros, memoria RAM y hasta un disco rudimentario dentro de los pesos del modelo.

Para quienes operan estos modelos en producción, el tamaño fijo del estado importa por una razón práctica: la memoria que ocupa cada conversación activa en un servidor no depende de cuánto lleva hablando el usuario. Eso simplifica decisiones de capacidad que, con atención estándar y su KV-cache creciente, se vuelven más difíciles de predecir a medida que las conversaciones se alargan.

Cómo funciona la regla delta por dentro

Cada cabeza de atención lineal con compuerta guarda un estado: una matriz que funciona como su memoria. En cada token, antes de escribir nada nuevo, el estado se multiplica por la compuerta, un número entre 0 y 1. Una compuerta de 0.9 va borrando un poco todo lo guardado en cada paso; una compuerta de 1.0 no borra nada.

Después de la compuerta, la cabeza ajusta una dirección del estado hacia un nuevo valor, y la fuerza de escritura (beta) decide cuánto. Con beta en 1.0, el valor viejo en esa dirección se reemplaza por completo en vez de mezclarse. Y si la clave que marca esa dirección es one-hot (un vector de ceros con un único 1), la escritura cae exacto en una sola fila de la matriz, igual que una dirección de memoria apunta a una sola celda de RAM.

El truco no está en entrenar un modelo nuevo, sino en fijar tres números que ya existían en la arquitectura: la compuerta, la fuerza de escritura y la forma de la clave. No hace falta ni un parámetro adicional.
La atención lineal con compuerta ocupa 3 de cada 4 capas de atención en Qwen3-Next.

flowchart TD
A["Token generado por Qwen3.5"] --> B["Clave one-hot: un solo 1 entre ceros"]
B --> C["Compuerta ajustada a 1.0"]
C --> D["Fuerza de escritura beta = 1.0"]
D --> E[("Fila de la matriz de estado")]
E --> F["Escritura exacta: sobrescribe esa fila"]
Enter fullscreen mode Exit fullscreen mode

Este diagrama resume el camino de una sola escritura. La lectura funciona igual, pero al revés: una consulta one-hot selecciona la misma fila y la devuelve sin mezclarla con ninguna otra.

graph LR
A["Atención estándar"] --> B["KV-cache crece con cada token"]
C["Atención lineal con compuerta"] --> D["Estado de tamaño fijo por cabeza"]
Enter fullscreen mode Exit fullscreen mode

La diferencia de fondo es esta: la atención estándar nunca olvida nada porque guarda todo el historial, mientras que la atención lineal con compuerta decide activamente qué conservar. Ajustar esa decisión a los extremos es lo que convierte el olvido controlado en memoria exacta.

Ejemplos prácticos: simular la memoria en unas líneas de Python

No hace falta tener los pesos de Qwen3.5 para ver por qué el truco funciona. Estos dos ejemplos reproducen el comportamiento de una sola cabeza de atención lineal con numpy, sin ningún framework de deep learning.

El primer ejemplo muestra el comportamiento por defecto: una compuerta menor a 1.0 hace que un valor guardado se desvanezca con el tiempo.

import numpy as np

estado = np.array([8.0])
compuerta = 0.5

for paso in range(3):
    estado = estado * compuerta

print(estado[0])
Enter fullscreen mode Exit fullscreen mode

Cada paso multiplica el estado por la compuerta sin escribir nada nuevo. Después de tres pasos, la salida es exactamente 1.0: el valor original, 8.0, se diluyó a la octava parte.

El segundo ejemplo fija la compuerta en 1.0 y usa una clave one-hot para escribir y leer una fila exacta, el mismo ajuste que usa Qwenputer.

import numpy as np

memoria = np.zeros((8, 4))  # 8 direcciones, 4 valores por celda

def escribir(memoria, direccion, valor):
    memoria[direccion] = valor  # compuerta=1.0 y beta=1.0: sobrescritura directa
    return memoria

def leer(memoria, direccion):
    clave = np.zeros(8)
    clave[direccion] = 1.0  # codificacion one-hot
    return clave @ memoria

memoria = escribir(memoria, 3, np.array([7, 0, 0, 0]))
print(leer(memoria, 3))
Enter fullscreen mode Exit fullscreen mode

La salida es [7. 0. 0. 0.]: la fila 3 guardó el valor exacto y la consulta one-hot lo recuperó sin tocar ninguna otra dirección. Esa es, en miniatura, la operación que Qwenputer repite miles de veces para mover datos entre los registros de su CPU.

Casos de uso reales de esta memoria lineal

Sobre esa base, Agrawal compiló un CPU RISC-V RV32IM completo (con la extensión Zba y una pequeña unidad para aritmética de números grandes) dentro de 11 de las 32 capas de Qwen3.5. El compilador traduce cada instrucción en pasos de "leer este registro", "sumar estos dos números" o "saltar si es cero", y cada paso se convierte en pesos de atención y de las capas que hacen de RAM.

flowchart TD
subgraph Modelo["Qwen3.5 4B: 32 capas en total"]
CPU["Primeras 11 capas: CPU RISC-V compilado"]
Resto["21 capas restantes: pesos originales de Qwen3.5"]
end
CPU --> Resto
Enter fullscreen mode Exit fullscreen mode

Según reporta el propio artículo original, ese CPU pasa las pruebas oficiales de riscv-tests, sus resultados coinciden con los de QEMU, y corrió 18 millones de instrucciones de forma autónoma sin un solo error. Qwen3.5 no invoca este CPU como una herramienta externa: genera los tokens de dirección, valor y fin de instrucción como parte normal de su texto, y esos tokens disparan las capas que hacen de hardware.
Qwenputer corrió 18 millones de instrucciones RISC-V sin un solo error registrado.

sequenceDiagram
participant Q as Qwen3.5
participant R as CPU RISC-V
participant M as Estado de atencion lineal
Q->>R: token ADDR
Q->>R: token VAL
Q->>R: token STEP
R->>M: escribe VAL en la fila ADDR
M-->>R: confirma escritura
R-->>Q: resultado de la instruccion
Enter fullscreen mode Exit fullscreen mode

Con esa misma base, el experimento corre código en C y en MicroPython dentro de los pasos hacia adelante del modelo, aunque todavía lento, y el autor sumó un sistema de archivos rudimentario que usa el mismo truco de direcciones one-hot para simular un disco. Dos proyectos derivados exploran los riesgos del mismo mecanismo: uno muestra cómo un modelo híbrido podría esconder parte de su razonamiento en el estado de la RNN lineal de Qwen para evadir la supervisión de su cadena de pensamiento, ya que un monitor que solo lee el texto generado no vería nada guardado directamente en esa memoria. El otro propone lo contrario: usar pesos compilados como este CPU como un auditor interno que el propio modelo no puede reentrenar ni manipular durante la inferencia, porque ese circuito no se aprendió, se fijó a mano.

Errores comunes y buenas prácticas

  • Confundirlo con tool calling. Qwenputer no llama a una herramienta externa ni corre en un sandbox: el CPU vive dentro de los mismos pesos que generan el texto, y el "driver" solo carga el firmware inicial en el estado.- Asumir que Qwen3.5 ya hace esto por defecto. Sin la modificación, el modelo usa una compuerta menor a 1.0, así que no guarda valores exactos, solo una mezcla aproximada del historial reciente.- Esperar rendimiento de silicio real. El propio autor aclara que no es un chip de clase Linux: corre más lento que un intérprete normal y, por ahora, se limita a aritmética y programas pequeños.- Tratar la regla delta como si fuera nueva. La memoria asociativa basada en la regla delta viene de 2021; lo nuevo es hacerla exacta y direccionable dentro de un modelo en producción.

Comparativa: atención estándar, atención lineal con compuerta y otras alternativas

La tabla siguiente resume cómo cada mecanismo guarda y recupera información, y cuándo conviene pensarlos como memoria.
MecanismoTipo de memoriaCosto por tokenLectura exactaAtención estándar (transformers clásicos)KV-cache completo, crece con la conversaciónSube con el largo del contextoNo necesita: pondera todo el historialAtención lineal con compuerta (Qwen3.5 por defecto)Estado de tamaño fijo, con desvanecimientoConstante por tokenNo: la compuerta mezcla valores viejos y nuevosAtención lineal con compuerta modificada (Qwenputer)Estado de tamaño fijo, direccionable fila por filaConstante por tokenSí: compuerta en 1.0 y clave one-hotModelos de espacio de estados (Mamba y similares)Estado recurrente comprimidoConstante por tokenNo: la memoria queda distribuida, no por direcciones

Profundizando: límites y matemática avanzada

La regla delta generalizada que usa Gated DeltaNet no solo multiplica por la compuerta: también resta la proyección de la clave actual antes de sumar el nuevo valor, lo que evita que una escritura arruine por completo lo que había antes en direcciones parecidas. Con clave one-hot esa resta desaparece, porque dos claves one-hot distintas son ortogonales por definición, y por eso el caso de Qwenputer se simplifica a una sobrescritura limpia fila por fila.

El costo de esta memoria también es distinto al de la atención estándar: una cabeza de atención lineal con compuerta mantiene un estado de tamaño fijo, mientras que el KV-cache de la atención completa crece linealmente con cada token nuevo. Esa diferencia es la que hace viable usar la capa como RAM: escribir y leer cuesta lo mismo en el token 10 que en el token 10.000. No hay una forma directa de verificar este costo desde afuera del modelo sin acceso al código de inferencia, pero la arquitectura de Qwen3-Next documenta públicamente qué capas usan atención lineal y cuáles usan atención completa.

Los límites son reales. El propio proyecto aclara que el CPU implementa el set RV32IM completo pero no es, todavía, un chip de clase Linux, y que ejecutar C o MicroPython dentro de los pasos hacia adelante del modelo es notablemente más lento que un intérprete normal. El autor también señala que el experimento, por ahora, se queda en aritmética y programas pequeños: ir más allá, como manejar memoria virtual o interrupciones reales, queda como trabajo futuro.

💭 Clave: nada de esto necesitó reentrenar el modelo. El compilador fija los pesos a mano, capa por capa, como quien cablea un circuito en vez de enseñarle a aprenderlo.

📖 Resumen en Telegram: Ver resumen

Tu próximo paso: abrí el repositorio de Qwenputer en Hugging Face o GitHub y seguí el log de una instrucción simple de suma para ver los tokens de dirección, valor y fin de instrucción generarse uno por uno.

Preguntas frecuentes

¿Qué es Qwenputer?

Qwenputer es una versión modificada de Qwen3.5 4B en la que un CPU RISC-V RV32IM queda compilado directamente en los pesos del modelo, usando la atención lineal con compuerta del propio modelo como memoria RAM.

¿Qwen3.5 usa esta memoria exacta por defecto?

No. Por defecto, la compuerta de Qwen3.5 es menor a 1.0, así que el estado se va desvaneciendo con cada token nuevo. Qwenputer fuerza la compuerta a 1.0 para que la memoria deje de perderse.

¿Qué es la regla delta?

Es la regla de actualización que usa la atención lineal con compuerta: en cada token, ajusta una dirección del estado hacia un nuevo valor según la fuerza de escritura (beta), en vez de reescribir toda la matriz.

¿Por qué el estado de esta memoria no crece con la conversación?

Porque cada cabeza guarda una matriz de tamaño fijo, a diferencia del KV-cache de la atención estándar, que agrega una fila por cada token nuevo del historial.

¿Se puede ejecutar código real dentro de los pesos de Qwen3.5?

Sí, de forma experimental: Qwenputer corre programas en C y MicroPython usando el CPU compilado en sus capas, aunque de forma más lenta que un intérprete convencional y sin soporte para un sistema operativo completo.

Referencias

📱 ¿Te gusta este contenido? Únete a nuestro canal de Telegram @programacion donde publicamos a diario lo más relevante de tecnología, IA y desarrollo. Resúmenes rápidos, contenido fresco todos los días.

Top comments (0)