Qwenx86-4B (compact)

Qwenx86: Qwen writes C, the x86 computer in the weights compiles and executes it (actual recorded execution)

โ–ถ๏ธ See it in action: Qwenx86 Debugger Space. Walk through actual recorded tool calls: the conversation, x86 registers and flags, code at the program counter, RAM and machine output, with all verified blocks on a timeline.

Qwen3.5-4B with a 64-bit x86 computer compiled into its weights: 13 transformer layers ahead of Qwen's own. There are no learned weights in them; all of their weights are computed by a compiler. Qwen invokes the computer through its own tool calls (<tool_call>), and the computer in the weights executes the tool. Calculator, Python, C compiler, notes store, physics/chemistry lookup and Python-docs lookup are all firmware in the checkpoint. This is the compact checkpoint: ~9 GB GPU memory, so it fits on a 16 GB GPU.

v2 adds Qwenx86 memory on the same weights: a filesystem, 1,000-fact store, 50,000-token verbatim recall, JPEG images, programmable heads, a search index, exact 64-bit arithmetic and state snapshots (see Qwenx86 memory). Those run beside the model and are driven by host code; the x86 tools run entirely in the weights.

v3 lets Qwen use that memory by itself: in a chat it decides when to save, read, search, list and delete notes, and writes the tool calls on its own (see New in v3).

From Qwenputer: circuit and machinery (see Credits for details)

  • The CPU circuit itself. The Qwenx86 core is a fork of Qwenputer's RV32 core (rv/core.py): fetch, ROM, RAM (delta-rule memory cells in Gated DeltaNet state), register file, branches, multiply/divide and bignum unit, designed by divagr1925.
  • The compiler that converts the circuit to Qwen3.5 layers. Tool-call bridge. Chat loop. State injection. Merge layout. MicroPython build.

New for Qwenx86

  • x86 in the core. Added x86 flag micro-ops (FADD, FSUB, FAND, FOR, FXOR, FINC, FDEC) and conditional jumps (JCC with the x86 condition table) to the forked circuit. Added a translator from x86-64 to the core's 32-bit ops (64-bit values as register/RAM halves, flags rebuilt per instruction, bridge ports, a single shared return dispatch).
  • Memory map. 64 KB RAM (the circuit grew from 11 to 13 layers). Read-only data wired to the x86 path.
  • Firmware and tools. All firmware (calc, the qcc C compiler, notes, science and python_doc stores, an x86 machine that decodes raw x86 bytes with SSE and interrupts). Code to patch the MicroPython build into a tool. Baking the firmware into the checkpoint.
  • Running. Compact 16 GB loader. Block verification.
  • v2 memory. Named files, facts, word-for-word recall, images, functions, a search index, exact arithmetic and saved reading state, all on the released weights.

My previous projects (neural-n64, neural-x86-doom, neural-riscv) demonstrated what it takes to exactly emulate a real CPU. This model does it in the weights of a language model.

Architecture graph for Quazim0t0/Qwenx86-4B-compact. Open in hfviewer

Qwenputer vs Qwenx86

Qwenputer Qwenx86
CPU RV32IM + Zba (RISC-V) core x86-64 core: a fork of the RV32 circuit with x86 flag micro-ops and conditional jumps
Programs RISC-V code x86-64 integer code from MSVC-compiled C, translated to core ops (the python tool still runs on the core's RISC-V path)
Chip layers 11 13
RAM 32 KB 64 KB
Read-only data 128 KB 128 KB, also wired to the x86 path
x86 decoder, semantics, tests none from my Zen2 research; 2,000/2,000 lockstep cases vs Unicorn
Tools calc and MicroPython (RISC-V builds) calc, python (Qwenputer's MicroPython, patched), c (qcc), notes, science, python_doc, all baked into the checkpoint as boot states
Running chat loop with the chip layers per token same loop + compact 16 GB loader + block verify (up to 256 machine tokens per pass)
Memory a filesystem (a separate checkpoint) v2: files, facts, word-for-word recall, images, functions, a search index, on the same weights (qwenx86/memory/)
Shared base compiler (chipformer), tool-call bridge, chat loop, state injection, merge layout the same, reused under MIT

What's in it

Part What it is
x86-64 core 13 chip layers (64 RAM heads, 16-bit program counter). Qwenputer's RV32 circuit, forked, with x86 flag ops, conditional jumps and 64 KB RAM added. x86 decoding, semantics and tests from my Zen2 research. Runs the integer instruction set used by compiled C: 8/16/32/64-bit ALU (incl. ADC/SBB), shifts, rotates, MUL/IMUL/DIV/IDIV, MOVZX/MOVSX, SETcc/CMOVcc, BT/BTS/BTR/BTC, BSF/BSR, string ops with REP, calls and returns. Verified against Unicorn on 2,000 lockstep cases: all registers and flags after each instruction. MSVC-compiled C is translated once into the core's own ops.
Memory 64 KB RAM, 256 KB code ROM, 128 KB read-only data. All in the model's Gated DeltaNet state.
Firmware in the checkpoint 6 boot states (model/boot/*.safetensors). Each loads a tool's entire machine (code, data, registers, PC) from the checkpoint. No program loading on the host side.
x86 machine firmware x86vm (in the dev tree, not shipped as a tool in this release). Decodes raw x86-64 bytes at run time. SSE doubles in software (bit-identical to a real SSE unit on 3,200 random ops). Interrupts (IDT, INT n, IRETQ, STI/CLI, HLT, timer). Ran hello for 1.44 M tokens through the compiled circuit, 0 wrong.

Tools Qwen calls (all answered by the computer in the weights)

Tool Firmware Notes
calc exact rational calculator in C (+ - x / parens decimals) GSM8K (first 28 test questions): 26/28 with calc vs 23/28 plain Qwen
python MicroPython (Qwenputer's prebuilt RISC-V build, patched to read the tool call) one-line expressions print their value; long programs in #more parts
c qcc, a small C compiler + runner for this core int, char, unsigned, long, pointers, arrays, functions, recursion, if/while/for, printf; long programs in //more parts
notes_put / notes_search / notes_get notes store in machine RAM no host routing; the notes are the machine's saved state
science 647 CODATA constants, unit conversions and the periodic table (NIST / scipy.constants), inverted index in read-only data exact recall 647/647, retrieval@1 98.0%
python_doc 1,003 Python API signatures + docstrings, grammar-compressed (204 KB -> 110 KB) in read-only data exact recall 1,003/1,003

Qwenx86 memory (new in v2)

v2 gives the model a memory it can write to and read back exactly: named files, a store of facts, long documents recalled word for word, images, small functions, a search index, exact arithmetic, and saved reading state. It uses the same weights as v1 (nothing retrained or re-merged); the code is in qwenx86/memory/. Every result below was measured on these weights, from this folder.

How to use it: v2/README.md.

How it works, and what it is not:

  • Where the memory lives. Each of four of the model's layers (13-16) gets extra memory slots of the same kind the layer already uses (DeltaNet state). Ordinary text can't write to them or wear them down, so Qwen's own answers are exactly the same whether the memory is full or empty.
  • What is not in the weights. The extra slots are run by code alongside the model, not stored as new weights. Finding a file by name (hashing it, comparing names, stepping through the directory) is also ordinary Python. So unlike the x86 tools above, which run entirely inside the model, the memory is driven from outside it, and in v2 you use it through Python calls (v3 adds a chat where Qwen calls it itself).
  • How text comes back out. Stored text is printed through the model's own final layer: each stored token is turned into a signal the output layer turns back into that same token.
Feature What it does Result
Named files save, read, add to, delete and list files by name 51 files saved and all read back correctly after restarting; 400 random operations, 0 mistakes; Qwen's answers unchanged afterwards
Facts 1,000 short facts stored and looked up by subject all 1,000 correct after restarting; unknown subjects answer "not found"
Word-for-word recall a 50,000-token document stored as one file read back with 0 errors in 50,000 tokens; 100 random passages printed by the model, 0 errors
Printing stored text the model writes stored text out itself a 104-token passage printed exactly in a single step, 13x faster than token by token
Images 20 JPEG pictures stored byte by byte all 20 come back identical; Qwen's vision encoder sees them exactly as it saw the originals
Functions small lookup functions (squares, primes, bit tricks, a 128x128 matrix) written into blank memory slots at run time 10,000 inputs, 0 wrong; the matrix within 0.2 %
Search index find the stored passage that answers a question 100 % correct for a word-matching index (16-128 passages); 90 % for pictures; a meaning-based text index is weak (59 % at best)
Exact arithmetic add, subtract, AND and XOR on 64-bit numbers using compiled lookup tables 1,000 / 1,000 correct; plain Qwen3.5-4B got 979 of the same 1,000 wrong
Saved reading state read a document once, save the model's state, answer questions later without the document 4 / 4 questions answered correctly from the saved state, matching a full re-read

Notes: the arithmetic tables come from the author's Zen2 work and ship as model/atoms.safetensors (60 KB). The image features use Qwen3.5-4B's own vision encoder, loaded separately, because this checkpoint is text-only. Background reading: docs/state_writes.md (why writing to this kind of memory doesn't need a full model run) and docs/d1_trace.html (every table lookup behind the arithmetic results, checked by an independent program, 0 mismatches).

New in v3: Qwen uses its memory itself

In v2 you drive the memory from Python. In v3, Qwen does it: in a chat it gets five memory tools (save, read, search, list, delete), decides when to use them, and writes the tool calls itself. Python carries out each call and hands the result back, the same way the v1 tools answer. The memory is saved after every message, so it is still there in the next chat. Same weights as v1 and v2; nothing retrained.

A real chat on the released model:

you> Remember that my locker number is 412. Save it in your memory.
  [memory_save {"name": "locker_number", "text": "412"} -> saved]
qwen> Okay, I've saved your locker number as 412.
you> What is my locker number? Check your memory.
  [memory_read {"name": "locker_number"} -> 412]
qwen> Your locker number is 412.
Test Result
Session 1: save three notes (wifi, dentist, bike), then delete wifi Qwen called memory_save three times and memory_delete once, all succeeded
Session 2, a separate process that only gets the saved memory Qwen found the dentist appointment and the bike code with its own searches, listed "dentist, bike", and said it had no wifi note: 4 / 4

Every tool in one chat. python -m qwenx86.mixed offers all eleven tools at once: the six v1 tools, run by the computer in the weights, and the five memory tools, run by Python. Qwen picks; the chat sends each call to the right place. A v1 call still runs inside the model with every machine token checked against the reference, exactly as in v1.

Session You say Tool Qwen called Run by Result
1 "What is 1234 * 5678? Use the calc tool." calc the computer in the weights, 43,770 machine tokens 7006652
1 "Save a file called locker with the memory_save tool: my locker number is 412." memory_save the memory (Python) saved
1 "Write a C program that prints 6 * 7 and run it with the c tool." c the computer in the weights, 169,293 machine tokens 42
1 "Save a note called bike with the notes_put tool: the bike lock code is 7193." notes_put the computer in the weights, 117,746 machine tokens saved
1 "What is my locker number? Use the memory_search tool." memory_search the memory (Python) 412
1 "What is my bike lock code? Use the notes_search tool." notes_search the computer in the weights, 125,199 machine tokens 7193
2 "What is my locker number? Use the memory_search tool." memory_search the memory (Python) 412
2 "What is my bike lock code? Use the notes_search tool." notes_search the computer in the weights, 125,197 machine tokens 7193

All 8 right, each call went to the tool Qwen named, and 0 of 581,205 machine tokens differed from the reference.

How to use it: v3/README.md.

The tests

Is the model still Qwen?

  • Text match vs stock Qwen3.5-4B. 3 normal text prompts (48 token positions) run through both stock Qwen and Qwenx86. The most likely next token is the same at each position (48/48). The distributions have a KL divergence of 4.1e-4; the layer widening alone is ~5e-4. So the computer layers don't change Qwen's own behavior.
  • Text logits with memory loaded. Qwen's text logits differ by exactly 0.0 between notes/store state loaded and empty. No leakage of computer state into Qwen's text.

Is the CPU a proper x86-64 CPU?

  • Instruction coverage (2,000 cases). 4 generators from my Zen2 research: general instructions, 2-byte opcodes, multiply/divide, string. 500 cases each. Each case runs on our core and on Unicorn (a real x86-64 emulator) in lockstep. All 16 registers and all flags x86 defines must be the same after each instruction. 2,000 / 2,000.
  • Compiled C programs. MSVC-compiled C programs (hello, a small library with string/sort routines, a program with recursion/multiply/divide/hex print) run on our core and on Unicorn. Printed output and registers after each instruction are the same.
  • Through the compiled circuit. The same programs run through the actual transformer layers (not just the reference), token by token: hello 386, lib 16,370, prog 358,501 tokens, 0 wrong each.
  • 64 KB RAM. A program that fills and reads back the upper 32 KB (new in this model) prints the same checksum as on Unicorn.

Do the firmwares compute the correct answers?

  • calc. 125 expressions (random arithmetic + GSM8K-like steps with decimals). Exact fraction arithmetic. Same firmware on Unicorn. 0 wrong.
  • python. 9 programs through the bridge: 2**100, sums, list comprehensions, recursion, an error traceback, strings, a 3-part #more program. Correct output in chat framing.
  • c (qcc). 10 programs: sum of squares, recursive Fibonacci, prime counting, strings, pointers, unsigned long long, divide by zero, a syntax error, a too-long call, a 3-part //more program. Each output is as expected AND the same as the same firmware on Unicorn.
  • notes. 10 operations: save, replace, case-insensitive get, search, no match, not found.
  • science. All 647 records looked up by name: 647/647 exact. 849 natural queries: correct record first 98.0% of the time (the word-overlap ceiling). The firmware's answer is the same as a Python copy of its algorithm for all 1,496 lookups.
  • python_doc. All 1,003 records looked up by name, decompressed byte-exact: 1,003/1,003. An unknown name answers "not found".

Does it work as a chat on real weights?

  • Live chats on a 16 GB card (compact checkpoint, computer booted from the baked firmware, block verify): Qwen wrote the tool call, the machine executed it, and Qwen replied based on the result. 0 lock errors in all cases. These are the runs shown in the Space; times include recording the debugger frames.
Chat What happened Machine tokens Time
calc (1200 - 350) / 5 = 170 56,667 41.0 s
python 2**100 = 1267650600228229401496703205376 39,526 46.8 s
c Qwen wrote a C program that prints 6 * 7. Compiled and executed: 42 169,293 71.2 s
notes 1) "save a note called bike..." saved. 2) Same chat: "what's the code?" -> 7193 117,746 + 74,798 81.6 s
science Avogadro constant: 6.02214076e+23 mol^-1 402,834 128.9 s
python_doc math.gcd signature: math.gcd(*integers) 55,684 44.3 s
  • Notes across processes. Save notes in one process, write the machine state to disk, boot a new process from it. All 3 notes found.
  • GSM8K with calc (first 28 test questions, greedy). 26/28 with the calc tool, 23/28 with just Qwen. 31 calc calls, 2.2 M machine tokens, 0 lock errors.
  • Speed. A C chat (168,578 machine tokens): 582 s token by token, 44.5 s with block verify (13x).

Screenshots

All runs from the Space, at the end of the run.

C compiler Notes
Science Python docs
Python Calculator

Run it

Needs a CUDA GPU with 16 GB of memory (the model uses ~9 GB, plus room for the run), Python 3.12 and the packages from requirements.txt (PyTorch with CUDA, transformers==5.22.1).

pip install -r requirements.txt
python -m qwenx86.run --tool calc    "What is (1200 - 350) / 5? Use the calc tool."
python -m qwenx86.run --tool c       "Write a C program that prints 2 to the power 40. Run it with the c tool."
python -m qwenx86.run --tool python  "What is 2 to the power 100 exactly? Use the python tool."
python -m qwenx86.run --tool science "What is the Avogadro constant? Use the science tool."
python -m qwenx86.run --tool pydoc   "What is the signature of math.gcd? Use the python_doc tool."
python -m qwenx86.run --tool notes   "Save a note called bike. The bike lock code is 7193."
python -m qwenx86.run --tool notes   "What's the code for my bike lock? Check your notes."

Run from this folder. The model loads in ~25 s. The transcript goes to stdout; the summary (machine tokens, verified blocks, lock status) goes to stderr. The notes tool stores its memory in ./qwenx86_notes/.

The v2 memory checks (results and saved state go to ./qwenx86_memory/):

python -m qwenx86.memory files save
python -m qwenx86.memory files load
python -m qwenx86.memory facts save
python -m qwenx86.memory facts load
python -m qwenx86.memory verbatim
python -m qwenx86.memory arithmetic
python -m qwenx86.memory images save
python -m qwenx86.memory images load

python -m qwenx86.memory lists them all; how to use the memory is in v2/README.md.

v3, a chat where Qwen uses the memory itself, and one chat with every tool (v3/README.md):

python -m qwenx86.memory chat
python -m qwenx86.mixed

Files

Path Contents
config.json a copy of model/config.json at the top of the repo, where the Hub counts downloads
model/compact.safetensors compact weights (8.75 GB): all maps' nonzero rows x columns
model/boot/*.safetensors baked machine states for the 6 tools
model/*.json, tokenizer config, chipformer.json (merge layout), Qwen tokenizer
machines/*.pkl, tools.json reference parked machine for each tool (checks all tokens), tool schema
qwenx86/ runtime: loader, x86 core circuit, uop machine, block verify, CLI
qwenx86/memory/ v2: the memory and its checks (python -m qwenx86.memory)
model/atoms.safetensors v2: the arithmetic lookup tables, 60 KB
docs/ v2: state_writes.md, d1_trace.html
v2/README.md v2: how to use the memory
v3/README.md v3: the memory chat
chipformer/ Qwenputer's compiler and RISC-V core and tools (MIT, Divyansh Agrawal)

Limits

  • Code per tool call: ~60 tokens per part (the bridge captures 80 tokens of a tool call). Longer programs go in //more / #more parts (up to 3,000 chars).
  • The x86 translator has no indirect jumps and no hardware SSE (x86vm does SSE in software, but is not shipped as a tool). The python tool is Qwenputer's minimal MicroPython build (e.g. no slice steps, a small heap).
  • Long runs: the longest local chat was 814,561 machine tokens (science, "atomic mass of iron", 202 s); machine tokens skip Qwen's layers, so they don't fill Qwen's KV cache.
  • Memory (v2): it runs alongside the model and is driven by Python code, not by the model itself. File names are at most 6 tokens.
  • Memory chat (v3): qwenx86.memory chat offers only the memory tools; qwenx86.mixed offers every tool. With both note systems available, name the tool you want, or Qwen picks one.
  • Speed: the machine makes 1 token per step. Block verify batches the checks, but a C compile + run is 0.1โ€“6 M machine tokens.
  • x86 decoding: programs are translated to core ops before running. Raw x86 bytes are decoded by firmware, not by circuit layers. Qwenputer also stores RISC-V code pre-decoded.
  • Qwen's text: Qwen3.5-4B's text, unmodified, and not trained on these tools. It sometimes restyles a tool's value in its answer (e.g. 6.02214076e+23 -> 6.02214076 ร— 10ยฒยณ).

Credits

  • Qwenputer by Divyansh Agrawal (@divagr1925, github.com/divagr18/qwenputer, MIT) is the base of this model. From Qwenputer:
    • chipformer: the compiler that converts the circuit to Qwen3.5 layers (q35 IR, emitter, primitives). Included here unmodified, MIT license (chipformer/LICENSE).
    • The RV32 core (chipformer/rv/core.py), with delta-rule memory cells, ROM, DROM and the bignum unit. Qwenx86's x86 core is a fork of it (+ x86 flag uops, conditional jumps, 64 KB RAM).
    • The tool-call bridge (rv/bridge.py): captures <tool_call>, runs the machine, echoes the output to the chat. The reference Session for checking all tokens.
    • The chat loop (rv/chat.py, RvChat). HF emission/state injection (rv/hf.py). The merge layout (rv1). The circuit executor. The nonzero block compaction idea (q35/fast.py).
    • The MicroPython build (mpy-s1.elf, from Qwenputer's tests). We patch it word by word into the python tool.
    • v2 memory: the design of the file store follows Qwenputer's filesystem (divagr1925/Qwen3.5-4B-Qwenputer-Filesystem): how tokens are packed into memory slots, how names are found in the directory, the size limits, and keeping Qwen's own layers untouched while the memory is used. The code that runs it on Qwenx86, the printing and the tests are our own.
  • From my previous work: the x86-64 reference and atoms from my Zen2 research, and lessons from neural-n64, neural-x86-doom and neural-riscv.
  • Model weights: Qwen/Qwen3.5-4B (Apache-2.0). Qwen's own weights are unmodified. Data: NIST CODATA / scipy.constants (public domain), periodictable (public domain), CPython docstrings (PSF license). Unicorn was used as the x86 reference for tests.

Citation

If you use this model, please cite this model and Qwenputer, which it is based on:

@misc{quazim0t02026qwenx86,
  author       = {Quazim0t0},
  title        = {{Qwenx86}: 64-bit x86 computer compiled into weights of {Qwen3.5-4B}},
  year         = {2026},
  publisher    = {Hugging Face},
  howpublished = {\url{https://huggingface.co/Quazim0t0/Qwenx86-4B-compact}},
  note         = {x86 side from author's Zen2 research. CPU circuit forked from Qwenputer}
}
@software{agrawal2026qwenputer,
  author  = {Agrawal, Divyansh},
  title   = {{Qwenputer}: a computer compiled into the weights of a pretrained language model},
  year    = {2026},
  version = {0.1.0},
  url     = {https://github.com/divagr18/qwenputer},
  license = {MIT}
}

License

The weights are Apache-2.0 (a modified version of Qwen/Qwen3.5-4B, LICENSE-Qwen3.5). We widen the config and add the computer layers, but don't modify Qwen's own weights. chipformer/ is MIT, ยฉ 2026 Divyansh Agrawal (chipformer/LICENSE).

Downloads last month
-
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support

Model tree for Quazim0t0/Qwenx86-4B-compact

Finetuned
Qwen/Qwen3.5-4B
Finetuned
(1,289)
this model

Space using Quazim0t0/Qwenx86-4B-compact 1