qwenFS: il filesystem che vive nei pesi di un LLM, senza API né plugin

Un filesystem completo compilato nei pesi di Qwen3.5-2B: 8 layer transformer calcolati a mano, nessun addestramento, e il modello salva, legge e collega i propri file tramite tool call. Tutto dentro lo stato Gated DeltaNet.

qwenFS: il filesystem che vive nei pesi di un LLM, senza API né plugin

Un filesystem completo compilato direttamente nei pesi di un modello linguistico. Non un plugin, non un database dietro un’API, non un server di tool esterni. Otto layer transformer aggiunti davanti ai 24 di Qwen3.5-2B, e nessuno di quei pesi è stato addestrato: sono tutti calcolati a tavolino, per costruzione.

qwenFS è l’ultimo esperimento di Vishal Baraiya, lo stesso autore di qwenGPU — quel progetto dove una GPU SIMT completa viveva nei pesi di Qwen. Stesso principio, nuova applicazione: stavolta il modello salva, legge, organizza e collega i propri file attraverso le sue normali tool call. E risponde a ogni chiamata da solo.

Come funziona, layer per layer

Qwen scrive le sue solite tool call in formato Qwen3.5. Il circuito legge ogni chiamata mentre Qwen la produce, un token alla volta, riconoscendo i token chiave che il formato usa sempre: =name, =text, =target, >, newline, . Dopo la chiusura del tag, il circuito stampa la risposta del tool in un turno utente, come vuole il chat template di Qwen, poi apre un nuovo turno assistant e Qwen risponde.

Sette operazioni disponibili: write_file salva (o sovrascrive), read_file recupera il testo token per token, list_files elenca tutto, link_files collega un file a un altro, unlink_files rimuove quel collegamento, list_links e list_backlinks navigano il grafo. I path creano cartelle (people/alice.txt, projects/cafe.txt); i link e i backlink fanno il resto.

Dove vivono i dati

Ogni parte del modello ha un compito preciso. L’attenzione tiene i file: il testo di una scrittura rimane nel log di attenzione del copy layer, indicizzato per (indice file, versione, offset); una lettura è una copia esatta, token per token. Una seconda testa di attenzione fa da lookup: un path trova l’indice del suo file, o cade su ‘not found’.

Lo stato Gated DeltaNet — la memoria ricorrente che Qwen3.5 usa al posto dell’attenzione classica in 18 layer su 24 — tiene le tabelle e i registri: tabella delle versioni, tabella dei path (per i listing), contatore dei file, stato della chiamata corrente, e i link. Un link è una riga di stato per ogni coppia (sorgente, target): link_files la scrive, unlink_files la svuota, quindi niente duplicati. Le righe memorizzano il loro bit nella colonna del target e in quella della sorgente, e una query multi-hot sulle righe di un file legge tutti i suoi link, o tutti i suoi backlink, in una volta sola.

Gli MLP parsano le tool call e scelgono ogni token forzato: gli ack, il frame della risposta, i path ripetuti, il prossimo link da elencare. Gli offset vengono da un contatore DeltaNet decadente, letto nel regime eps della head norm e decodificato in modo esatto fino a 600 token.

Precisione assoluta

Ogni token porta una dimensione ‘ballast’, così ogni norma nei layer FS è una scala fissa. I registri riempiono le loro righe di stato a 2, 8, 32 o 128 ‘rail’ prestabiliti, quindi le letture tornano esattamente come 0/1 o ±1. Una chiave spenta sta molto sotto lo zero, perché la norma l2 di una chiave DeltaNet riscalerebbe qualsiasi valore piccolo a piena potenza.

qfs.merge allarga il residuo di Qwen da 2048 a 3072, fa zero-padding delle sue matrici, scala i gain delle norme per √(2048/3072), mette i layer FS davanti a quelli di Qwen e appende i token FS al vocabolario. I layer FS azzerano le loro dimensioni prima che girino quelli di Qwen, tranne un piccolo codice di output che il lm_head tied legge alla fine: così un token forzato vince, e i logit di Qwen restano intatti ovunque.

Disco e sessioni persistenti

Un filesystem si salva in un’immagine compatta: i path, l’ultimo testo di ogni file come ID token a 3 byte, e i link. Circa 3,3–3,8 byte per token memorizzato. Una sessione fresca monta l’immagine — tabelle e righe di lookup — e carica il testo di un file solo quando il modello emette l’ack di lettura di quel file. Il paging ricostruisce le righe di copia dagli ID token usando le proiezioni del modello stesso.

I pesi gestiscono tutto: parsing di ogni chiamata, ogni lookup, ogni aggiornamento di tabella, ogni token forzato, ogni token copiato di una lettura. Niente fuori dal modello decide cosa dice una risposta. Il loop di chat (qfs/chat.py) decodifica i token e si ferma a <|im_end|>, campiona a temperatura 0,7. Con greedy decoding un 2B tende a ripetere le tool call; i token forzati guidano con centinaia di logit di vantaggio, quindi il sampling non li tocca mai. Quando il modello emette un ack di lettura, il runtime (qfs/disk.py) carica i byte di quel file, come un controller disco: il modello sceglie il file e copia il testo. Il pannello dell’app (qfs/monitor.py) legge il filesystem dallo stato del modello — tabelle di versioni, path e link — senza tenere copie proprie.

La documentazione come system prompt

docs/fs-agent.md è il system prompt di default per Qwen: un riferimento per i tool, le loro risposte e le convenzioni, con esempi dettagliati. Ogni risposta di esempio nel documento è stata stampata dal modello mergato (qfs/gen_doc.py).

Su 6 scenari (salva e recupera, aggiorna una lista, organizza, link e backlink, unlink, file mancante), 3 seed, 48 turni totali:

  • Senza doc: 46/48 turni passati, 17/18 scenari passati, 6 chiamate non necessarie
  • Con il doc: 48/48 turni passati, 18/18 scenari passati, 0 chiamate non necessarie

Il campione è piccolo, certo. Ma il calo nelle chiamate superflue è l’effetto più netto.

Risultati dichiarati

Su Qwen3.5-2B, su Apple silicon (MPS, bf16), l’autore riporta:

  • Sessioni scriptate di scritture, sovrascritture, cancellazioni, nomi mancanti, link, link ripetuti, unlink e listing (16 file): ogni token forzato esatto, 74/74 chiamate per sessione
  • Un grafo denso: un file collegato a e da tutti gli altri 31, un duplicato e un self-link, poi unlink all’inizio, metà e fine. Esatto
  • Da disco, in una sessione fresca con contesto vuoto: esatto
  • Mergato in Qwen3.5-2B, in contesto e da disco: esatto
  • Predizione top-1 di Qwen invariata in tutte le 139 posizioni controllate; KL circa 2e-3 (dall’arrotondamento dei gain di norma riscalati a bf16)

Circa 20 token/s su MPS, kernel PyTorch fallback per Gated DeltaNet. Accettabile, non fulmineo.

Limiti dichiarati

32 file massimo, path fino a 8 token, circa 590 token per scrittura, 63 versioni per file; un testo non può contenere </. Niente ricerca dentro i file e nessuna modifica parziale: cambiare un file significa riscriverlo tutto. Il punto debole è il giudizio di Qwen, non il filesystem: a volte risponde dalla conversazione invece di leggere un file, o fa chiamate che nessuno gli ha chiesto. Servono circa 16 GB di memoria libera per il modello mergato.

Il contesto: CPU e filesystem compilati nei pesi

qwenFS non è solo. qwenGPU, dello stesso autore, compila una GPU SIMT a 4 lane nei pesi di Qwen3.5-2B: 45 layer davanti ai 24 di Qwen, capace di eseguire codice CUDA reale compilato in NVIDIA PTX. Nessun peso appreso, tutto calcolato.

Qwenputer di Divyansh Agrawal compila invece una CPU RISC-V a 32 bit nei pesi di Qwen3.5-4B: 11 layer davanti a quelli di Qwen, stato Gated DeltaNet usato come RAM. Tom's Hardware ha riportato che esegue DOOM e codice C, con checkpoint che salgono a quasi 19 GB e almeno 24 GB di VRAM consigliati. Qwenputer ha anche una variante sperimentale con filesystem: directory hash da 1.024 slot, fino a 512 file e circa 53.000 token di testo, hidden size 4608.

qwenFS parte da Qwen3.5-2B, usa 8 layer senza CPU, gestisce fino a 32 file e si usa tramite le normali tool call di Qwen. La variante filesystem di Qwenputer, secondo la sua scheda, gestisce il filesystem internamente senza tool call esterne. Nessun legame dichiarato tra i due progetti.

Quickstart e repo

Requisiti: Python 3.11+, uv, just, e circa 16 GB di memoria libera. Apple silicon, GPU NVIDIA o CPU.

git clone https://github.com/vixhal-baraiya/qwenFS && cd qwenFS
just setup
just build
just chat

just build scarica Qwen3.5-2B e compila il filesystem dentro. just chat apre l'app di chat: ogni tool call si vede come una riga con la risposta del circuito sotto, e il pannello a destra mostra il filesystem come il modello lo tiene, decodificato dal suo stato DeltaNet dopo ogni risposta: file e cartelle, link, layer FS che si accendono mentre agiscono, e il disco. /save memorizza il filesystem (in fs/ di default), /mount avvia una nuova chat su uno memorizzato, i cui file vengono caricati quando Qwen li legge; /help elenca il resto.

just ask 'Save notes/todo.txt: call the dentist' 'What's on my todo list?' manda messaggi senza l'app. just elenca ogni ricetta: test (il circuito da solo, Qwen non serve), test-disk, test-tui (l'app su una sessione scriptata), check (il modello mergato) ed eval (aggiungi --doc docs/fs-agent.md per usare il doc).

Il codice è MIT. Un checkpoint costruito con qfs.merge è un modello Qwen3.5 modificato — config allargato e layer filesystem aggiunti, pesi di Qwen invariati tranne i gain di norma riscalati — e ricade sotto la licenza Apache 2.0 di Qwen. Fatene quello che volete, anche commercialmente.

Gated DeltaNet: la memoria che rende tutto possibile

Senza Gated DeltaNet, qwenFS non esisterebbe. È l'architettura di attenzione lineare presentata nel paper 'Gated Delta Networks: Improving Mamba2 with Delta Rule' di Songlin Yang (MIT CSAIL), Jan Kautz e Ali Hatamizadeh (NVIDIA), pubblicato a ICLR 2025. Prima versione su arXiv: 9 dicembre 2024.

Combina due meccanismi: il gating, che cancella rapidamente la memoria, e la delta rule, che aggiorna associazioni chiave-valore mirate. Integrato in Qwen3-Next e nella serie Qwen3.5, dove 18 layer su 24 usano Gated DeltaNet al posto dell'attenzione completa. È quello stato ricorrente che qwenFS usa per tenere tabelle, registri e link del filesystem.

Qwen3.5-2B: 24 layer, hidden size 2048 (allargato a 3072 da qfs.merge), schema ibrido 6 × (3 × Gated DeltaNet → FFN, 1 × Gated Attention → FFN), 8 teste query e 2 key-value, FFN intermedia 6144, vocabolario 248.320 token, embedding condivisi con lm_head, contesto nativo 262.144 token. Rilasciato a febbraio 2025. Apache 2.0.

Scritto da

Michel Morelli

Sviluppatore full-stack da oltre 26 anni. Integro l'IA in siti, e-commerce e gestionali, e ogni giorno racconto le novità dell'intelligenza artificiale su ZioBuddaLabs.

Vuoi l'IA al lavoro nella tua azienda?

Una call di 30 minuti, senza impegno. Oppure scrivi a michel@ziobuddalabs.it