PYNQ-Z1 · BitNet b1.58 · FPGA

Development journal開発記録

How a ternary language model ended up generating text on a hobbyist Zynq board, with the matrix multiplications and attention running on circuits written by hand. One entry per stretch of work, written at the time. Wrong turns and later corrections are left in.

三値の言語モデルを、PYNQ-Z1 の FPGA に自分で書いた回路で動かすまでの記録です。 区切りごとにその時点で書いたもので、途中の誤りと後からの訂正もそのまま残してあります。

To run it yourself, see the repository README.

New to FPGAs? Start with 01. Just want the result? Read 05. FPGA が初めてなら 01 から。いまの到達点だけなら 05 を。
  1. 012026-09-05Stages 0–1

    From CPU to FabricCPU からファブリックへ

    What a Zynq chip is, why memory bandwidth rather than multipliers sets the speed limit, and the first measurement of how fast the fabric can read DDR.

    Zynq とは何か、なぜ速さを決めるのが掛け算器ではなく帯域なのか、そして PL から DDR を読む速さを初めて測った話。FPGA 初心者向けの入口。

    Later corrected · 後の訂正 The "PL uses 74% of DDR" reading was wrong: it was the datapath width, not DDR (see 02). Notes marking this are in the page. 「PL は DDR の 74%」という読みは誤りで、当たっていたのは道幅だった(02 を参照)。本文にも印を付けてある。
  2. 022026-09-08Stage 2

    Two Ceilings二つの天井

    Separating two different limits — the datapath width on the fabric side and the DDR itself — and finding the real ceiling with two HP ports.

    PL 側の道幅と DDR そのものという二つの天井を切り分け、HP ポート 2 本で本当の上限を見つけるまで。

    Later corrected · 後の訂正 1.97 GB/s was re-measured as 2.01 GB/s once the fixed overhead of each measurement was removed (see 04). The argument doesn't change. 1.97 GB/s は、測定の固定費を除いて測り直すと 2.01 GB/s だった(04 を参照)。切り分けの筋は変わらない。
  3. 032026-09-08Stages 2–4

    The Wall Doesn't Move壁は動かない

    Computing right up to the bandwidth wall with an INT8 multiplier array, then getting 4.8× more weights through the same wall by going ternary — with zero DSP slices. An update adds the bad news: attention on the CPU dominates.

    INT8 の掛け算器で壁まで計算し、三値にして同じ壁から 4.8 倍の重みを取り出すまで。DSP は 0 個。追記で、CPU に残した attention が全体を支配すると分かる。

    Later corrected · 後の訂正 Bandwidth figures here are 1–4% low (measurement overhead, see 04). The CPU baseline was compiled without NEON, so CPU times were about 1.8× too slow (see 04 and 05). 帯域の数字は 1〜4% 低い(測定の固定費、04 を参照)。比較相手の CPU は NEON 無効で焼いていたので、CPU の時間は約 1.8 倍遅く出ていた(04・05 を参照)。
  4. 042026-09-18Stages 5a–5b

    Reaching the Wall壁に届いた

    Attention as a two-phase circuit. Softmax turns out to cost no bandwidth at all, and all four circuits sit at the DDR wall. Along the way, the way bandwidth had been measured since stage 1 turns out to be wrong.

    attention を 2 相の回路にする。softmax は帯域を 1 バイトも食わず、4 本の回路がすべて DDR の壁に張り付く。途中で、段階1 からの帯域の測り方が間違っていたと分かる。

  5. 052026-09-28Stages 6–11

    It Runs End to End通しで動いた

    Current · 現在地

    Rounding a normal model to ternary breaks it, so the project switches to a model trained ternary. Stream headers, a rebuilt attention core, scatter-gather DMA for the KV cache — and text generated on the board, with logits bit-identical to a Mac. 7.3 tok/s at 512 tokens of context.

    普通のモデルを三値に丸めたら壊れたので、三値で学習したモデルに乗り換える。見出し付きストリーム、attention の作り直し、KV を流す SG 転送を経て、ボードで文章を生成。Mac と logits がビット単位で一致し、文脈 512 で 7.3 tok/s。