まず「重みの中で動く」とは何を指すのか
ふつう「モデルの重み」は、推論のたびに参照される固定パラメータです。そこに別の計算機を“入れる”という発想は、メタファーとしては面白いものの、実際にはかなり曖昧に聞こえます。Qwenputer の面白さは、その曖昧さを比喩ではなく、前段の層として具体化しているところにあります。単に「LLM が計算した」ではなく、重みの並び方そのものを計算機の回路図に見立てているのです。
この実験の土台は Qwen3.5-4B です。説明では、stock の Qwen3.5 に 32-bit RISC-V CPU を直接コンパイルして挿入したとされます。しかも CPU は外付けのツールやサンドボックスではありません。モデルの forward pass の内側で、生成されるトークン列そのものを使って進みます。外から Python を呼ぶのとは違い、呼び出し先がモデルの中にある。この違いが、話を一段ややこしくしています。
ここで重要なのは、「学習で作った」のではなく「コンパイラが各重みを計算した」とされている点です。普通のニューラルネットは、データから重みを最適化して得ます。だがこの場合、重みは CPU の構成要素として直接与えられる。素朴に見ればただの再配線ですが、実際にはレジスタ、プログラムカウンタ、データ、命令の流れまでがモデルの層へ写像されているわけで、かなり別物です。
見た目は奇抜でも、比喩として読むと少し理解しやすいです。Qwen が文章を続ける横で、内部には小さな 32-bit CPU が回っている。しかもその CPU は、言語モデルの外ではなく、言語モデルの計算グラフの中にいる。ここで次に気になるのは、「じゃあ RAM はどこにあるのか」という一点です。そこがこの仕掛けの本体になります。
記憶を担うのは、注意機構ではなく DeltaNet の状態
Qwenputer の説明でいちばん異様なのは、CPU の RAM が別メモリではなく、Qwen3.5 の Gated DeltaNet の状態だという点です。Gated DeltaNet は、arXiv の Gated Delta Networks 論文で示されている、ゲートと delta ルールを組み合わせた線形 RNN 系の仕組みです。ざっくり言えば、毎トークンごとに状態を更新し、その更新が記憶として残ります。ここでの「記憶」は、KV キャッシュのような単純な保存とは少し違う。
README では、この状態に対して、ゲートを 1、書き込み強度を 1、さらに one-hot key を使うと、各書き込みがちょうど 1 行を上書きし、one-hot query でその値をそのまま取り出せると説明されています。RAM のように使える、という主張です。別の言い方をすると、ふつうならぼんやりとしか残らない RNN の内部状態を、アドレス指定できるメモリに変えている。ここが「学習ゼロで RAM にした」という表現の下支えになっています。
手元にある数字も、この見立てを少し具体化します。説明では、RAM の読み書きは DeltaNet の状態に依存し、CPU のコード、データ、レジスタ、プログラムカウンタまでそこに置かれるとされます。さらに filesystem 版では、ディレクトリだけで 1,024 スロット、保存できるファイルは最大 512、総量は約 53,000 トークンと書かれています。1 ファイルあたりの実用性を考えると、単なるおもちゃではなく、モデル内部の状態をかなり広く“物置”にしているのが分かります。
ただし、この時点ではまだ「どうやって exact に読み書きできるのか」の核心には触れていません。なぜ one-hot で 1 行だけを正確にいじれるのか。なぜ途中で誤差が積もらないのか。そこは後半で扱う部分として伏せておくとして、前半で押さえるべきなのは、従来のアテンションの発想ではなく、RNN の状態そのものを RAM 化している、という入口です。
コンパイラが CPU を“重みへ”焼き込む
CPU をモデルに入れる、というと訓練済みモデルに後付けで小さな論理回路をぶら下げたように見えますが、実態はもっと機械的です。説明では、CPU は回路として記述され、そこから「このレジスタを読む」「この 2 つを足す」「ゼロなら飛ぶ」といった小さな手順へ分解されます。そしてコンパイラが、それぞれを transformer layer の部品に変換する。注意ヘッドは参照、MLP は演算、DeltaNet は RAM という役割分担です。
ここでの実装は RV32IM に Zba 拡張を加え、さらに大きな整数用の bignum unit を載せた 32-bit RISC-V core です。Qwen の前に 11 層の chip layer が置かれ、残り 32 層が通常の Qwen3.5 側です。つまり、モデルの前段に“計算機の層”があり、その出力を通常の言語モデルが受け取る構成になっています。Qwen 全体は単一の生成器でありつつ、内部に別の命令系統が走る、という形です。
この手の仕掛けは、従来なら tool use に近いものとして理解されがちです。実際、Qwenputer は tool-call 形式を流用して指示を受け取るそうですが、外部の実行環境は動きません。モデルが calc っぽい形式で命令を書き、同じ forward pass の内部で CPU がそれを解釈し、結果をまたテキストとして返す。外から見れば API 呼び出しに似ていますが、裏で動いているのは別プロセスではなく、重みでできた CPU です。
この構成が気持ち悪いほど面白いのは、言語モデルの「出力トークン」がそのまま機械語の実行痕跡になるからです。トークンが命令列であり、命令列が実行ログであり、実行ログがまた文章として表に出る。自然言語と機械語の境目を、同じ重みの中で往復している。では、その往復が本当に壊れずに回るのか。そこが次の問いです。
何がうまくいったのか、数字だけ先に見る
README とブログにあるベンチマークを見ると、これは単なるデモ以上の成績を出しています。Synthetic integer arithmetic では base Qwen3.5-4B が 75.0 に対し、Qwenputer は 97.5、Python tool を使うベースも 97.5 です。DeepMind の mul_big は 55.0 から 97.5 へ、div_big は 72.5 から 97.5 へ上がっています。mul_div_multiple_longer は 90.0 から 100.0。add_or_sub_big は 87.5 から 97.5 です。
ブログでは、NUPA の長整数算術で base の 48.6% が 100% まで跳ね上がる、とされています(README ではこの数字は初代の CHIP-8 版の表に載っています)。しかも計算結果の出力位置については、約 230,000 個を参照機械と突き合わせて、ミスマッチは 0 だったと報告されています。さらに Qwen の普通のテキスト挙動は base とほぼ同等で、KL は 6e-4、ノイズフロアは 5e-4 です。つまり、CPU を埋め込んでも会話能力を大きく壊していない、という主張です。
filesystem 版でも面白い値が出ています。multi-session recall は base の 7.8 に対して 83.3、変更された事実の想起は 3.3 から 90.0。Python tool 版は 78.9 と 83.3 なので、内部に保存した状態がかなり効いていることになります。ここだけ見ると、外部ツールを使った補助にかなり近い性能を、モデル内部だけで再現しているように見えるわけです。
ただ、ここで満足すると肝心な部分を見落とします。なぜこの仕掛けで exact な算術が成立するのか、どこまでが CPU 側の正しさで、どこから先が Qwen 側の言語生成なのか。その境界と限界が、この話の本題です。そこを明かす前に、まずは「埋め込まれた CPU が本当に CPU なのか」を確認したくなるはずです。そこから先が、かなりおもしろい。
👉 続き(核心はここから)は PaPoo で読めます: https://papoo.work/doc/c4262ae5f5e44dd3

