apex-inference-chip README

The project's README from github.com/SigmanticAI/apex-inference-chip. As one markdown file: README.md.

APEX — tinyNPU: the attention engine that remembers

A fully open, verification-first LLM-inference tile. One transformer decoder layer in real RTL — attention, KV-cache compression, softmax, RMSNorm, RoPE, SwiGLU, residual — every block bit-exact against an executable golden model, running real Qwen models through the verified pipeline, and brought up on real FPGA hardware. Pre-silicon, and every number in this repo is labeled as what it is: measured or projected.

TL;DR for the impatient: GPUs are built to compute. This tile is built to remember. It does the attention math in hardware and compresses the conversation's memory (the KV cache) in the same datapath, so reading speed is designed to stay flat as the context grows. Verified numbers live one click away: STATUS.md · results index · master table.


Table of contents

  1. Why this exists
  2. The architecture
  3. The KV-compression engine
  4. How we know it's right
  5. Real models through the pipeline
  6. On real hardware
  7. Performance: what's measured, what's projected
  8. Repository layout
  9. Reproduce everything
  10. Method, prior art, and provenance
  11. License
  12. Roadmap

1. Why this exists

Large-model inference has two costs that dominate everything else at the edge: moving weights and remembering context. The first is a bandwidth problem. The second — the KV cache — is the quietly growing one: every token you've read must be stored and re-read on every new token, so a long conversation turns an inference engine into a memory-traffic engine.

Most accelerators treat the KV cache as a software problem: quantize it on the CPU/GPU, store it, hope. APEX's bet is architectural: put the KV codec inside the datapath, so keys and values are compressed the moment they are produced and decompressed the moment they are consumed — with an importance unit that watches which parts of the context actually matter and spends bits where they count.

The second bet is methodological: nothing ships without a bit-exact golden model. Every RTL block in this tree is verified against an executable NumPy reference — not "close", not "within tolerance": bit-identical, with mutation-tested testbenches and machine-generated evidence under an anti-fabrication rule. See §4.

The scope is deliberately honest: this is one tile — no DRAM controller, no PCIe, no NoC (out of scope by charter). The architecture is demonstrated end-to-end on real Qwen2.5-0.5B on FPGA hardware. The architecture is sized for 7B-class models (head_dim = 128 exists in RTL, and Qwen2.5-7B tokens have run through the software-verified golden pipeline — not through silicon), and the paper-architecture that wraps the tile into a full chip is specified with per-number provenance in docs/spec/APEX7B_SPEC.md.


Built with Sigmantic AI

APEX was developed with the help of Sigmantic AI's verification tooling. Sigmantic AI builds autonomous verification agents that take hardware from natural-language spec to verified RTL — real UVM testbenches, real simulators, honest sign-off. Underneath is the Polaris Engine: a closed-loop planner that treats verification as scientific discovery, choosing at every step the one simulation that will reveal the most about your design.

The Polaris Engine — verification as scientific discovery: a closed loop that runs, each cycle, the one simulation that reveals the most.

2. The architecture

APEX-7B block diagram

One decode step through the tile

A single new token enters as an activation vector x; the tile produces the layer output y. Everything between is hardware:

              ┌──────────────────────────── apex_top ─────────────────────────────┐
              │                                                                   │
  x ──► seam ─┼─► RMSNorm ──► MXE: W_Q·x  W_K·x  W_V·x ──► RoPE ──► KVQ compress  │
              │    (ASU)      (systolic GEMM)              (Q,K)        │         │
              │                                                         ▼         │
              │                                     KV cache — INT4 + outlier     │
              │                                     lane, on-tile SRAM            │
              │                                                         │         │
              │              ┌──────────────────────────────────────────┤         │
              │              ▼                                          │         │
              │   MXE: Q·K̂ᵀ ──► online softmax ──► MXE: P·V̂             │         │
              │                    (ASU)              │                 │         │
              │        ▲                              │                 │         │
              │        └────── TIP importance ◄───────┤                 │         │
              │               (adaptive precision)    ▼                 │         │
              │                          MXE: W_O·attn ──► + residual ──┼──► y    │
              │                                                         │         │
              │   FFN: RMSNorm ──► MXE: W_gate/W_up ──► SwiGLU ──► MXE: W_down    │
              │                                                    ──► + residual │
              └───────────────────────────────────────────────────────────────────┘

Six ideas make this a tile rather than a pile of blocks:

Block-by-block tour

block dir what it does
MXE rtl/mxe INT8 systolic GEMM engine — all seven matrix jobs of the layer, time-multiplexed
KVQ rtl/kvq the KV-cache codec: per-channel INT4 keys / per-token INT4 values, fp16 outlier lane, precision tiers — compression in the datapath (§3)
ASU rtl/asu the nonlinear unit: online softmax, RMSNorm (narrow + wide), SiLU/SwiGLU — exhaustively verified against golden
RoPE rtl/rope rotary position embedding applied to Q and K in-flight
TIP rtl/tip token-importance tracking → per-region precision tier decisions
SEQ rtl/seq CSR file, job decoder, and the layer walker — the on-tile sequencer (§ below)
SEAM rtl/seam ingress/egress: activation framing, quantization at the boundary, scale transport
XBR rtl/xbr the routing fabric that lets one engine's egress feed the next engine's ingress without host round-trips
TOP rtl/top apex_top — composition + glue (GQA engine banking, W4 ingest, composite scale caches)

The deep-dive is ARCHITECTURE.md — including the design-decision register and the module provenance history.

The layer walker: from job server to sequencer

The tile has two execution modes, and the difference is the project's central bring-up story:

  HOST MODE  (proven first)              WALKED MODE  (the destination)
  ──────────────────────────            ───────────────────────────────
  host builds each job                   host kicks ONCE per layer
   │  descriptor, one at a time           │
   ▼                                      ▼
  ┌────┐  job   ┌──────┐                ┌────────────┐ fetches its own
  │host│ ─────► │ tile │                │ seq walker │ descriptors, walks
  └────┘ ◄───── └──────┘                │  (on-tile) │ QKV→attn→OPROJ→
      result, each job                  └─────┬──────┘ residual→FFN→DOWN
      (~ms of host latency              ┌─────▼──────┐
       per job, ~100× tax)              │   engines  │ chained on-tile via
                                        └────────────┘ the XBR fabric

In host mode every job pays a host round-trip — correct, measurable, and roughly two orders of magnitude of throughput left on the table. The layer walker (rtl/seq, design notes in docs/design/B1_WALKER.md) replaces the host inside a layer: it fetches descriptors, sequences the engines, routes intermediate tensors through the fabric, and grades composite scales at every seam — so one kick executes a whole layer.

Walker status is tracked honestly in docs/design/MASTER_TABLE.md and docs/design/PROMPT_ON_CHIP.md: the walked layer is bit-exact in simulation (attention, norm, residual, FFN and DOWN composition), host-mode is proven on FPGA silicon, and walked attention on the FPGA is in active bring-up — a genuinely rare synthesis-vs-simulation defect was root-caused there (the story is worth reading: docs/results/prompt_on_chip/).

Feeding the beast: weight streaming

A real model's weights don't fit on a tile — they stream. The IB-FUEL lane (docs/design/IB_FUEL.md) gives the walker a fuel line from DDR: per-job weight records prefetched into an on-tile FIFO, so the GEMM engine contracts over streamed weights without stalling, and per-chunk records let the FFN's big matrices interleave with compute. The W4 lane (docs/design/W4_DATAPATH.md) halves that traffic again: weights travel as 4-bit groups and are unpacked to INT8 at the feeder, with group scales riding the same transport as the data they describe.

3. The KV-compression engine

The codec is the architectural heart. Per-channel INT4 keys, per-token INT4 values, an fp16 outlier lane for the channels that refuse to quantize, and tiered precision (KVQ8 / KVQ4 / KVQ4+) driven by measured token importance — the published on-device KV-quantization family (cf. KIVI, KVQuant), implemented as verified hardware.

What makes this implementation worth reading:

4. How we know it's right

The methodology is the product as much as the RTL is:

   spec ──► golden model (NumPy, executable) ──► frozen vectors
                 │                                   │
                 │ bit-exact arbiter                 ▼
                 └────────────► RTL ◄──── testbenches + SVA + coverage
                                 │            │
                                 │            └── mutation gates: break the
                                 │                RTL on purpose — the TB
                                 ▼                must catch every mutant
                        composition levels
              L1 block → L2 pipeline → L3 full layer vs golden
                                 │
                                 ▼
                 same jobs replayed on FPGA silicon, bit for bit

5. Real models through the pipeline

Not a toy trace: run_tinynpu.py --prompt streams greedy Qwen2.5-7B (through the software-verified golden pipeline — the FPGA-measured model is Qwen2.5-0.5B) — tokens through the golden fixed-point pipeline — the same executable arbiter the RTL is verified against — producing coherent text, with sampled hardware-shaped jobs traced and replayed bit-exact, and the trace's real-model K/V rows replayed through the KVQ RTL in simulation with zero mismatches. Full artifact run, scope, and counts: docs/results/s8_7b_token/.

Accuracy through the verified codec (full 10,042-document HellaSwag, measured, reproducible from a clone): near-lossless at 0.5B/1.5B; at 7B, KVQ8 shows no detectable effect at full-set power and KVQ4 a small, real, quantified cost — which is precisely why the outlier tier exists. Numbers, statistics, and honest caveats: docs/results/s5_eval7b/.

6. On real hardware

Two independent hardware existence proofs, different parts, different toolchains:

Run it yourself

The verified reference image is agfi-030a812cd224b409d (A2 recipe, 15.625 MHz tile; registered with its build receipt in scripts/fpga/f2/clock_key.py). These steps were executed verbatim against that image before this section was committed — battery 193 checks, 0 fails, then live prompts answered with every walked value graded bit-exact:

Measured throughput, harness-printed on silicon: 0.56 tok/s on the fastest registered image (A0, 62.5 MHz — steady 1.78 s/token, confirmed on two builds, all gates passing) and 0.25 tok/s on this reference image (A2, 15.625 MHz) — the full per-optimization ladder from the 0.004 tok/s host-driven baseline (a 140× measured climb) lives in docs/results/prompt_on_chip/FIRST_WALKED_TOKENS.md.

# prove the silicon: boots an f2.6xlarge, loads the image, flies the
# 193-check battery + walked chains, prints the verdict, terminates itself
bash scripts/fpga/f2/run_walked_demo.sh agfi-030a812cd224b409d

# talk to it: an interactive prompt CLI on the walked pipeline
# ("The capital of France is" -> " Paris.", graded end to end)
bash scripts/fpga/f2/run_chat_demo.sh

Requirements: AWS CLI credentials with F2 access (f2.6xlarge, us-west-2) and the team's model-weight artifacts (the DDR images derive from mlx-community/Qwen2.5-0.5B-Instruct-4bit; the staging bucket is configured in the scripts — external users should regenerate the weight image with `scripts/fpga/f2/make_weight_image.py

apex-inference-chip (SigmanticAI/apex-inference-chip)

Searching Database…

这是什么?APEX 是一个开放的、以验证为先的 LLM 推理硬件设计:用真正的 RTL 编写的一个 transformer 解码器层,可在 FPGA 上运行 Qwen2.5-0.5B,每个电路模块都经过与软件黄金模型逐位一致的校验。
这是一颗真正的芯片,还是在 FPGA 上运行的东西?它是 RTL(硬件描述)源码加上一个 Python/NumPy 黄金参考模型,而不是制造出来的硅片。该设计处于流片前阶段,在真实的 FPGA 开发板(Lattice ECP5-85F 和 AWS F2)上点亮调试,而不是作为成品芯片出售。
我怎么自己复现这些结果?克隆仓库,对照仓库内置的黄金模型和测试平台运行附带的 Python 脚本;runtinynpu.py 会让 Qwen2.5 提示词流经经过验证的定点流水线,FPGA 结果则可以对照已提交的比特流和 AGFI 镜像进行复现。
我需要一块 FPGA 开发板才能尝试吗?不需要——黄金模型验证和 Verilator 仿真完全可以在普通机器上用 Python 运行。真实的硬件结果则额外需要一块 Lattice ECP5-85F 开发板(开源工具链)或一个 AWS F2 Vivado/VU47P FPGA 实例。
快速注意力路径在真实硬件上可以用了吗?还没有完全就绪。主机模式执行已在 FPGA 硅片上得到验证,但更快的 walked-attention 路径(可避免每个算子的主机往返)仍在积极点亮调试中——此前在那里发现并定位了一个真实的综合工具缺陷。
这里的逐位一致验证到底是什么意思?每个 RTL 模块的输出都会与 NumPy 黄金模型逐值比对,不容忍任何不匹配;测试平台经过变异测试,当 RTL 被故意破坏时必须转为失败;而且根据反造假规则,所有公布的数据都由测试套件日志机器生成。
Sigmantic AI 在构建这个项目中扮演了什么角色?Sigmantic AI 提供了自主验证工具(Polaris 引擎),用于把设计从自然语言规格推进到经过验证的 RTL,在每一步挑选最有可能暴露设计缺陷的仿真。
为什么 KV 缓存对推理速度如此重要?在长对话中,每个过去 token 的键/值对都必须被存储,并为每个新 token 重新读取,这让推理变成一个内存带宽问题而非计算问题;APEX 在硬件数据通路内部压缩该缓存,按设计让读取流量随上下文增长保持得更平缓。
这种验证方法真的抓到过真实的硬件缺陷吗?有——在 walked-attention 点亮调试期间,真实 FPGA 采样与 Verilator 仿真孪生之间的差分测试锁定了一个真实的综合工具缺陷,表明是工具链(而非 RTL)在产生错误结果。
What are similar projects?Model-Optimizer, openTPU, ANE, MiniCPM, Edge0, backburner, DMI, jeeves
Size
7.7 MB
Stars
581
Updated
CommitAug 18
Age
2mo
Commits · 90 Days