Align claim verdicts with project vocabulary: 6 Refuted, 8 Inconclusive (was Disproven - overclaimed a confounded test)
Browse files
README.md
CHANGED
|
@@ -1,256 +1,256 @@
|
|
| 1 |
-
---
|
| 2 |
-
license: mit
|
| 3 |
-
language:
|
| 4 |
-
- en
|
| 5 |
-
library_name: cflow
|
| 6 |
-
tags:
|
| 7 |
-
- moe
|
| 8 |
-
- cpu-inference
|
| 9 |
-
- rust
|
| 10 |
-
- custom-architecture
|
| 11 |
-
- pipeline-native
|
| 12 |
-
- avx-512
|
| 13 |
-
datasets:
|
| 14 |
-
- roneneldan/TinyStories
|
| 15 |
-
- HuggingFaceFW/fineweb-edu
|
| 16 |
-
pipeline_tag: text-generation
|
| 17 |
-
model-index:
|
| 18 |
-
- name: arch2_4_combined
|
| 19 |
-
results:
|
| 20 |
-
- task:
|
| 21 |
-
type: text-generation
|
| 22 |
-
dataset:
|
| 23 |
-
name: TinyStories
|
| 24 |
-
type: roneneldan/TinyStories
|
| 25 |
-
metrics:
|
| 26 |
-
- name: Test Perplexity (114M, 10K steps)
|
| 27 |
-
type: perplexity
|
| 28 |
-
value: 6.50
|
| 29 |
-
- name: Top-1 Accuracy (114M, 10K steps)
|
| 30 |
-
type: accuracy
|
| 31 |
-
value: 56.8
|
| 32 |
-
- name: Val Perplexity (8.34B / 4-layer, 10K steps)
|
| 33 |
-
type: perplexity
|
| 34 |
-
value: 4.52
|
| 35 |
-
- name: Top-1 Accuracy (8.34B / 4-layer, 10K steps)
|
| 36 |
-
type: accuracy
|
| 37 |
-
value: 61.4
|
| 38 |
-
---
|
| 39 |
-
|
| 40 |
-
# arch2_4_combined — Pipeline-Native MoE for CPU Inference
|
| 41 |
-
|
| 42 |
-
A custom decoder-only transformer with delayed dense FFN + delayed MoE experts,
|
| 43 |
-
designed so its inter-layer dependency graph permits vertical pipelining on CPU.
|
| 44 |
-
Part of the **cflow** project — a CPU-first streaming inference engine written in
|
| 45 |
-
Rust.
|
| 46 |
-
|
| 47 |
-
> **Hosted weights:** this repository hosts `model.cflow` (17.39 GB) — the
|
| 48 |
-
> **arch2_4_8k_16l** model: 16 layers, hidden 8192, **~31B parameters**
|
| 49 |
-
> (top-2-of-8 MoE, ~20B active/token), Q4. This is the model benchmarked at
|
| 50 |
-
> 5.94 tok/s below. The **8.34B** figures in this card refer to a *smaller
|
| 51 |
-
> 4-layer scale point* (`arch2_4_8k_4l`) used for quality and cache-locality
|
| 52 |
-
> validation (val ppl 4.52); that checkpoint is not hosted here.
|
| 53 |
-
|
| 54 |
-
## Key Results
|
| 55 |
-
|
| 56 |
-
| Metric | Value |
|
| 57 |
-
|---|---|
|
| 58 |
-
| CPU decode throughput (~31B / 16-layer, Q4, 32 threads) | **5.94 tok/s** |
|
| 59 |
-
| Effective memory bandwidth | 61 GB/s (30% of 204.8 GB/s peak) |
|
| 60 |
-
| Bandwidth reduction from pipelining | **2.00x** (9.00 → 4.50 MB/token) |
|
| 61 |
-
| Test perplexity (114M, TinyStories, 10K steps) | 6.50 |
|
| 62 |
-
| Val perplexity (8.34B / 4-layer, TinyStories, 10K steps) | 4.52 |
|
| 63 |
-
|
| 64 |
-
### CPU Decode Benchmark (AWS r6i.8xlarge, Ice Lake Xeon, 256 GB DDR4)
|
| 65 |
-
|
| 66 |
-
| Engine | Model | Quant | tok/s |
|
| 67 |
-
|---|---|---|---|
|
| 68 |
-
| **cflow** | arch2_4_8k_16l (~31B MoE, ~20B active) | Q4 | **5.94** |
|
| 69 |
-
| Ollama (llama.cpp) | Qwen2.5-32B (32B dense) | Q4 GGUF | 4.75 |
|
| 70 |
-
| vLLM CPU | Qwen2.5-32B-Instruct (32B dense) | GPTQ-Int4 | 1.65 |
|
| 71 |
-
|
| 72 |
-
> **Note:** cflow and the baselines run different models — cflow's ~31B MoE has
|
| 73 |
-
> ~20B active params per token vs 32B dense. The total parameter counts are
|
| 74 |
-
> comparable (31B vs 32B), but the architectures and training differ, so the
|
| 75 |
-
> cflow number shows what a co-designed architecture + streaming runtime achieves,
|
| 76 |
-
> not a quality-matched result.
|
| 77 |
-
|
| 78 |
-
## Model Description
|
| 79 |
-
|
| 80 |
-
**arch2_4_combined** is a pre-norm decoder-only transformer with a parallel dense
|
| 81 |
-
FFN + sparse MoE block per layer, using delayed residual injection:
|
| 82 |
-
|
| 83 |
-
- The **dense FFN** reads from a delayed residual (1 layer behind)
|
| 84 |
-
- The **MoE experts** are routed on the current residual but injected 2 layers later
|
| 85 |
-
- This creates a dependency DAG where dense and expert weight reads for layer N
|
| 86 |
-
can overlap with compute for layer N-1, reducing critical-path memory bandwidth
|
| 87 |
-
|
| 88 |
-
The architecture was selected from a screen of 5 pipeline-native candidates. It
|
| 89 |
-
is the only design that achieves a measured bandwidth reduction (2.00x) while
|
| 90 |
-
maintaining competitive perplexity.
|
| 91 |
-
|
| 92 |
-
### Architecture Details
|
| 93 |
-
|
| 94 |
-
| Parameter | 114M (screening) | ~31B (16-layer, hosted) |
|
| 95 |
-
|---|---|---|
|
| 96 |
-
| Hidden dim | 512 | 8,192 |
|
| 97 |
-
| Layers | 6 | 16 |
|
| 98 |
-
| Attention heads | 8 | 128 |
|
| 99 |
-
| Head dim | 64 | 64 |
|
| 100 |
-
| Dense FFN hidden | 2,048 | 32,768 |
|
| 101 |
-
| Expert FFN hidden | 512 | 4,096 |
|
| 102 |
-
| Experts / top-k | 8 / 2 | 8 / 2 |
|
| 103 |
-
| Dense delay | 1 | 1 |
|
| 104 |
-
| Expert delay | 2 | 2 |
|
| 105 |
-
| Vocab | 50,257 (GPT-2 BPE) | 50,257 (GPT-2 BPE) |
|
| 106 |
-
| Max seq len | 512 | 2,048 |
|
| 107 |
-
|
| 108 |
-
### Per-Layer Forward Pass
|
| 109 |
-
|
| 110 |
-
```
|
| 111 |
-
attn_out = attention(attn_norm(x))
|
| 112 |
-
x = x + attn_out # residual connection
|
| 113 |
-
x = x + dense_ffn(ffn_norm(delayed_x)) # dense reads DELAYED residual
|
| 114 |
-
if queued_expert: x = x + queued_expert # inject expert from 2 layers ago
|
| 115 |
-
expert_out = moe(ffn_norm(x)) # router sees CURRENT residual
|
| 116 |
-
# expert_out queued for injection at layer + expert_delay
|
| 117 |
-
```
|
| 118 |
-
|
| 119 |
-
### Components
|
| 120 |
-
|
| 121 |
-
- **Attention:** Multi-head (not GQA), Q/K/V/O projections (no bias), standard
|
| 122 |
-
RoPE (base=10000, half-interleave), causal masking, KV cache
|
| 123 |
-
- **Dense FFN:** GeGLU — `down(gelu(gate(x)) * up(x))`
|
| 124 |
-
- **MoE:** Linear router → top-k selection → softmax over selected → per-expert
|
| 125 |
-
GeGLU FFN → weighted sum. No auxiliary/load-balancing loss.
|
| 126 |
-
- **Normalization:** RMSNorm (eps=1e-6) at attn input, FFN input, and pre-lm_head
|
| 127 |
-
- **Combine style:** `DelayedSum` — dense and router share `ffn_norm` but read
|
| 128 |
-
different residual snapshots
|
| 129 |
-
|
| 130 |
-
## Training
|
| 131 |
-
|
| 132 |
-
### 114M Screening (5 architectures)
|
| 133 |
-
|
| 134 |
-
| | |
|
| 135 |
-
|---|---|
|
| 136 |
-
| Dataset | TinyStories (431M train tokens, 24M test tokens) |
|
| 137 |
-
| Tokenizer | GPT-2 BPE (50,257 vocab) |
|
| 138 |
-
| Sequence length | 512 |
|
| 139 |
-
| Optimizer | AdamW (betas=0.9/0.95, eps=1e-8, weight_decay=0.1) |
|
| 140 |
-
| Learning rate | 3e-4 with linear warmup (200 steps) + cosine decay to 1e-5 |
|
| 141 |
-
| Gradient clipping | Global norm 1.0 |
|
| 142 |
-
| Batch size | 8 |
|
| 143 |
-
| Steps | 10,000 |
|
| 144 |
-
| Precision | float32 |
|
| 145 |
-
| Hardware | RTX 3060 12 GB |
|
| 146 |
-
|
| 147 |
-
### 8.34B Scale-Up (4-layer — quality & cache validation)
|
| 148 |
-
|
| 149 |
-
This is the smaller scale point: `arch2_4_8k_4l`, 4 layers, 8.34B params. It
|
| 150 |
-
provides the quality numbers (val ppl 4.52, top-1 61.4%) and the PMU cache-locality
|
| 151 |
-
result. The hosted decode-benchmark model (`arch2_4_8k_16l`, ~31B) shares this
|
| 152 |
-
per-layer geometry but has 16 layers.
|
| 153 |
-
|
| 154 |
-
| | |
|
| 155 |
-
|---|---|
|
| 156 |
-
| Dataset | TinyStories (same splits) |
|
| 157 |
-
| Optimizer | 8-bit AdamW (bitsandbytes) |
|
| 158 |
-
| Learning rate | 1e-4 with linear warmup (500 steps) + cosine decay to 1e-6 |
|
| 159 |
-
| Batch size | 4 per GPU (global 32) |
|
| 160 |
-
| Steps | 10,000 |
|
| 161 |
-
| Precision | bf16 |
|
| 162 |
-
| Parallelism | FSDP (FULL_SHARD / ZeRO-3) |
|
| 163 |
-
| Gradient checkpointing | Per `DelayedMoELayer`, non-reentrant |
|
| 164 |
-
| Hardware | 8x A100 SXM4 80 GB (Lambda Cloud) |
|
| 165 |
-
|
| 166 |
-
### Architecture Comparison (114M, TinyStories, 10K steps)
|
| 167 |
-
|
| 168 |
-
| Architecture | dense_delay | expert_delay | Test PPL | Top-1 Acc | BW Reduction |
|
| 169 |
-
|---|---|---|---|---|---|
|
| 170 |
-
| arch1_decoupled_streams | 0 | 0 | 7.21 | 54.9% | 1.00x |
|
| 171 |
-
| **arch2_4_combined** | **1** | **2** | **6.50** | **56.8%** | **2.00x** |
|
| 172 |
-
| arch3_pipeline_registers | 0 | 0 | 7.24 | 55.1% | 1.00x |
|
| 173 |
-
| arch4_async_experts | 0 | 2 | **6.26** | **57.6%** | 1.00x |
|
| 174 |
-
| arch5_fixed_point | 0 | 0 | 6.77 | 56.2% | 1.00x |
|
| 175 |
-
|
| 176 |
-
**Key insight:** Dense delay is the bandwidth knob; expert delay is the quality
|
| 177 |
-
knob. arch4_async_experts gets the best perplexity by routing off pre-dense
|
| 178 |
-
activations (cleaner router signal) but sacrifices the bandwidth win that
|
| 179 |
-
arch2_4 achieves by also delaying the dense read.
|
| 180 |
-
|
| 181 |
-
## Inference with cflow
|
| 182 |
-
|
| 183 |
-
cflow is a Rust inference engine that reads `.cflow` (per-layer streaming) or
|
| 184 |
-
`.vflow` (vertical pipeline) weight files. Weights are stored as pre-tiled Q4
|
| 185 |
-
(128x256 tiles, ~18 KB each, sized to fit L2 cache).
|
| 186 |
-
|
| 187 |
-
```bash
|
| 188 |
-
# Build
|
| 189 |
-
cargo build --release --bin cflow-run
|
| 190 |
-
|
| 191 |
-
# Convert safetensors → .cflow
|
| 192 |
-
cargo run --release --bin cflow-convert -- \
|
| 193 |
-
--input checkpoint.safetensors \
|
| 194 |
-
--output model.cflow \
|
| 195 |
-
--model arch2_4
|
| 196 |
-
|
| 197 |
-
# Run inference
|
| 198 |
-
CFLOW_THREADS=32 ./target/release/cflow-run \
|
| 199 |
-
model.cflow 32 \
|
| 200 |
-
--prompt "Once upon a time" \
|
| 201 |
-
--tokenizer tokenizer.json \
|
| 202 |
-
--temperature 0.8
|
| 203 |
-
```
|
| 204 |
-
|
| 205 |
-
### SIMD Support
|
| 206 |
-
|
| 207 |
-
The runtime auto-detects and dispatches to the best available instruction set:
|
| 208 |
-
|
| 209 |
-
| ISA | Kernel | Notes |
|
| 210 |
-
|---|---|---|
|
| 211 |
-
| AVX-512 + VNNI | Q4×Q8 `vpdpbusd` | Best path (Ice Lake+) |
|
| 212 |
-
| AVX-512F | Q4×f32 FMA | Skylake-X+ |
|
| 213 |
-
| AVX2 + FMA | Q4×f32 FMA | Haswell+ |
|
| 214 |
-
| AVX + SSE4.1 | Q4×f32 | Sandy Bridge+ |
|
| 215 |
-
| Scalar | Q4×f32 | Fallback |
|
| 216 |
-
|
| 217 |
-
## Limitations
|
| 218 |
-
|
| 219 |
-
- **Not a general-purpose LLM.** Trained on TinyStories / FineWeb-Edu subsets at
|
| 220 |
-
10K steps — this is an architecture and runtime research artifact, not a
|
| 221 |
-
production language model.
|
| 222 |
-
- **Custom architecture.** Cannot be loaded in Hugging Face Transformers, vLLM,
|
| 223 |
-
or llama.cpp without adaptation. Requires the cflow Rust runtime or the
|
| 224 |
-
PyTorch reference in `pipeline_native/`.
|
| 225 |
-
- **CPU-only.** The runtime targets x86-64 CPUs with AVX2 or AVX-512. No GPU
|
| 226 |
-
backend.
|
| 227 |
-
- **Single-token decode optimized.** Batch/prefill throughput is not the focus.
|
| 228 |
-
|
| 229 |
-
## Thesis Scorecard
|
| 230 |
-
|
| 231 |
-
The cflow project tests 8 claims about CPU inference optimization:
|
| 232 |
-
|
| 233 |
-
| # | Claim | Result |
|
| 234 |
-
|---|---|---|
|
| 235 |
-
| 1 | Conditional expert reading (top-k only) | **Proven** |
|
| 236 |
-
| 2 | Tile-streaming L1/L2 cache locality | **Proven** (7.29x fewer L1-d misses, PMU-measured) |
|
| 237 |
-
| 3 | AVX2/AVX-512 Q4 SIMD kernels | **Proven** |
|
| 238 |
-
| 4 | Fused QKV and gate+up projections | **Proven** |
|
| 239 |
-
| 5 | Compute-order file layout | **Proven** |
|
| 240 |
-
| 6 | Software prefetch (`_mm_prefetch`) | **
|
| 241 |
-
| 7 | Vertical pipeline via delayed dependencies | **Validated** (2.00x bandwidth reduction) |
|
| 242 |
-
| 8 | Stage-major disk layout readahead | **
|
| 243 |
-
|
| 244 |
-
## Citation
|
| 245 |
-
|
| 246 |
-
```bibtex
|
| 247 |
-
@software{poperszky2026cflow,
|
| 248 |
-
author = {Poperszky, Tom},
|
| 249 |
-
title = {cflow: CPU-First Streaming Inference for Pipeline-Native Transformers},
|
| 250 |
-
year = {2026}
|
| 251 |
-
}
|
| 252 |
-
```
|
| 253 |
-
|
| 254 |
-
## License
|
| 255 |
-
|
| 256 |
-
MIT
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
language:
|
| 4 |
+
- en
|
| 5 |
+
library_name: cflow
|
| 6 |
+
tags:
|
| 7 |
+
- moe
|
| 8 |
+
- cpu-inference
|
| 9 |
+
- rust
|
| 10 |
+
- custom-architecture
|
| 11 |
+
- pipeline-native
|
| 12 |
+
- avx-512
|
| 13 |
+
datasets:
|
| 14 |
+
- roneneldan/TinyStories
|
| 15 |
+
- HuggingFaceFW/fineweb-edu
|
| 16 |
+
pipeline_tag: text-generation
|
| 17 |
+
model-index:
|
| 18 |
+
- name: arch2_4_combined
|
| 19 |
+
results:
|
| 20 |
+
- task:
|
| 21 |
+
type: text-generation
|
| 22 |
+
dataset:
|
| 23 |
+
name: TinyStories
|
| 24 |
+
type: roneneldan/TinyStories
|
| 25 |
+
metrics:
|
| 26 |
+
- name: Test Perplexity (114M, 10K steps)
|
| 27 |
+
type: perplexity
|
| 28 |
+
value: 6.50
|
| 29 |
+
- name: Top-1 Accuracy (114M, 10K steps)
|
| 30 |
+
type: accuracy
|
| 31 |
+
value: 56.8
|
| 32 |
+
- name: Val Perplexity (8.34B / 4-layer, 10K steps)
|
| 33 |
+
type: perplexity
|
| 34 |
+
value: 4.52
|
| 35 |
+
- name: Top-1 Accuracy (8.34B / 4-layer, 10K steps)
|
| 36 |
+
type: accuracy
|
| 37 |
+
value: 61.4
|
| 38 |
+
---
|
| 39 |
+
|
| 40 |
+
# arch2_4_combined — Pipeline-Native MoE for CPU Inference
|
| 41 |
+
|
| 42 |
+
A custom decoder-only transformer with delayed dense FFN + delayed MoE experts,
|
| 43 |
+
designed so its inter-layer dependency graph permits vertical pipelining on CPU.
|
| 44 |
+
Part of the **cflow** project — a CPU-first streaming inference engine written in
|
| 45 |
+
Rust.
|
| 46 |
+
|
| 47 |
+
> **Hosted weights:** this repository hosts `model.cflow` (17.39 GB) — the
|
| 48 |
+
> **arch2_4_8k_16l** model: 16 layers, hidden 8192, **~31B parameters**
|
| 49 |
+
> (top-2-of-8 MoE, ~20B active/token), Q4. This is the model benchmarked at
|
| 50 |
+
> 5.94 tok/s below. The **8.34B** figures in this card refer to a *smaller
|
| 51 |
+
> 4-layer scale point* (`arch2_4_8k_4l`) used for quality and cache-locality
|
| 52 |
+
> validation (val ppl 4.52); that checkpoint is not hosted here.
|
| 53 |
+
|
| 54 |
+
## Key Results
|
| 55 |
+
|
| 56 |
+
| Metric | Value |
|
| 57 |
+
|---|---|
|
| 58 |
+
| CPU decode throughput (~31B / 16-layer, Q4, 32 threads) | **5.94 tok/s** |
|
| 59 |
+
| Effective memory bandwidth | 61 GB/s (30% of 204.8 GB/s peak) |
|
| 60 |
+
| Bandwidth reduction from pipelining | **2.00x** (9.00 → 4.50 MB/token) |
|
| 61 |
+
| Test perplexity (114M, TinyStories, 10K steps) | 6.50 |
|
| 62 |
+
| Val perplexity (8.34B / 4-layer, TinyStories, 10K steps) | 4.52 |
|
| 63 |
+
|
| 64 |
+
### CPU Decode Benchmark (AWS r6i.8xlarge, Ice Lake Xeon, 256 GB DDR4)
|
| 65 |
+
|
| 66 |
+
| Engine | Model | Quant | tok/s |
|
| 67 |
+
|---|---|---|---|
|
| 68 |
+
| **cflow** | arch2_4_8k_16l (~31B MoE, ~20B active) | Q4 | **5.94** |
|
| 69 |
+
| Ollama (llama.cpp) | Qwen2.5-32B (32B dense) | Q4 GGUF | 4.75 |
|
| 70 |
+
| vLLM CPU | Qwen2.5-32B-Instruct (32B dense) | GPTQ-Int4 | 1.65 |
|
| 71 |
+
|
| 72 |
+
> **Note:** cflow and the baselines run different models — cflow's ~31B MoE has
|
| 73 |
+
> ~20B active params per token vs 32B dense. The total parameter counts are
|
| 74 |
+
> comparable (31B vs 32B), but the architectures and training differ, so the
|
| 75 |
+
> cflow number shows what a co-designed architecture + streaming runtime achieves,
|
| 76 |
+
> not a quality-matched result.
|
| 77 |
+
|
| 78 |
+
## Model Description
|
| 79 |
+
|
| 80 |
+
**arch2_4_combined** is a pre-norm decoder-only transformer with a parallel dense
|
| 81 |
+
FFN + sparse MoE block per layer, using delayed residual injection:
|
| 82 |
+
|
| 83 |
+
- The **dense FFN** reads from a delayed residual (1 layer behind)
|
| 84 |
+
- The **MoE experts** are routed on the current residual but injected 2 layers later
|
| 85 |
+
- This creates a dependency DAG where dense and expert weight reads for layer N
|
| 86 |
+
can overlap with compute for layer N-1, reducing critical-path memory bandwidth
|
| 87 |
+
|
| 88 |
+
The architecture was selected from a screen of 5 pipeline-native candidates. It
|
| 89 |
+
is the only design that achieves a measured bandwidth reduction (2.00x) while
|
| 90 |
+
maintaining competitive perplexity.
|
| 91 |
+
|
| 92 |
+
### Architecture Details
|
| 93 |
+
|
| 94 |
+
| Parameter | 114M (screening) | ~31B (16-layer, hosted) |
|
| 95 |
+
|---|---|---|
|
| 96 |
+
| Hidden dim | 512 | 8,192 |
|
| 97 |
+
| Layers | 6 | 16 |
|
| 98 |
+
| Attention heads | 8 | 128 |
|
| 99 |
+
| Head dim | 64 | 64 |
|
| 100 |
+
| Dense FFN hidden | 2,048 | 32,768 |
|
| 101 |
+
| Expert FFN hidden | 512 | 4,096 |
|
| 102 |
+
| Experts / top-k | 8 / 2 | 8 / 2 |
|
| 103 |
+
| Dense delay | 1 | 1 |
|
| 104 |
+
| Expert delay | 2 | 2 |
|
| 105 |
+
| Vocab | 50,257 (GPT-2 BPE) | 50,257 (GPT-2 BPE) |
|
| 106 |
+
| Max seq len | 512 | 2,048 |
|
| 107 |
+
|
| 108 |
+
### Per-Layer Forward Pass
|
| 109 |
+
|
| 110 |
+
```
|
| 111 |
+
attn_out = attention(attn_norm(x))
|
| 112 |
+
x = x + attn_out # residual connection
|
| 113 |
+
x = x + dense_ffn(ffn_norm(delayed_x)) # dense reads DELAYED residual
|
| 114 |
+
if queued_expert: x = x + queued_expert # inject expert from 2 layers ago
|
| 115 |
+
expert_out = moe(ffn_norm(x)) # router sees CURRENT residual
|
| 116 |
+
# expert_out queued for injection at layer + expert_delay
|
| 117 |
+
```
|
| 118 |
+
|
| 119 |
+
### Components
|
| 120 |
+
|
| 121 |
+
- **Attention:** Multi-head (not GQA), Q/K/V/O projections (no bias), standard
|
| 122 |
+
RoPE (base=10000, half-interleave), causal masking, KV cache
|
| 123 |
+
- **Dense FFN:** GeGLU — `down(gelu(gate(x)) * up(x))`
|
| 124 |
+
- **MoE:** Linear router → top-k selection → softmax over selected → per-expert
|
| 125 |
+
GeGLU FFN → weighted sum. No auxiliary/load-balancing loss.
|
| 126 |
+
- **Normalization:** RMSNorm (eps=1e-6) at attn input, FFN input, and pre-lm_head
|
| 127 |
+
- **Combine style:** `DelayedSum` — dense and router share `ffn_norm` but read
|
| 128 |
+
different residual snapshots
|
| 129 |
+
|
| 130 |
+
## Training
|
| 131 |
+
|
| 132 |
+
### 114M Screening (5 architectures)
|
| 133 |
+
|
| 134 |
+
| | |
|
| 135 |
+
|---|---|
|
| 136 |
+
| Dataset | TinyStories (431M train tokens, 24M test tokens) |
|
| 137 |
+
| Tokenizer | GPT-2 BPE (50,257 vocab) |
|
| 138 |
+
| Sequence length | 512 |
|
| 139 |
+
| Optimizer | AdamW (betas=0.9/0.95, eps=1e-8, weight_decay=0.1) |
|
| 140 |
+
| Learning rate | 3e-4 with linear warmup (200 steps) + cosine decay to 1e-5 |
|
| 141 |
+
| Gradient clipping | Global norm 1.0 |
|
| 142 |
+
| Batch size | 8 |
|
| 143 |
+
| Steps | 10,000 |
|
| 144 |
+
| Precision | float32 |
|
| 145 |
+
| Hardware | RTX 3060 12 GB |
|
| 146 |
+
|
| 147 |
+
### 8.34B Scale-Up (4-layer — quality & cache validation)
|
| 148 |
+
|
| 149 |
+
This is the smaller scale point: `arch2_4_8k_4l`, 4 layers, 8.34B params. It
|
| 150 |
+
provides the quality numbers (val ppl 4.52, top-1 61.4%) and the PMU cache-locality
|
| 151 |
+
result. The hosted decode-benchmark model (`arch2_4_8k_16l`, ~31B) shares this
|
| 152 |
+
per-layer geometry but has 16 layers.
|
| 153 |
+
|
| 154 |
+
| | |
|
| 155 |
+
|---|---|
|
| 156 |
+
| Dataset | TinyStories (same splits) |
|
| 157 |
+
| Optimizer | 8-bit AdamW (bitsandbytes) |
|
| 158 |
+
| Learning rate | 1e-4 with linear warmup (500 steps) + cosine decay to 1e-6 |
|
| 159 |
+
| Batch size | 4 per GPU (global 32) |
|
| 160 |
+
| Steps | 10,000 |
|
| 161 |
+
| Precision | bf16 |
|
| 162 |
+
| Parallelism | FSDP (FULL_SHARD / ZeRO-3) |
|
| 163 |
+
| Gradient checkpointing | Per `DelayedMoELayer`, non-reentrant |
|
| 164 |
+
| Hardware | 8x A100 SXM4 80 GB (Lambda Cloud) |
|
| 165 |
+
|
| 166 |
+
### Architecture Comparison (114M, TinyStories, 10K steps)
|
| 167 |
+
|
| 168 |
+
| Architecture | dense_delay | expert_delay | Test PPL | Top-1 Acc | BW Reduction |
|
| 169 |
+
|---|---|---|---|---|---|
|
| 170 |
+
| arch1_decoupled_streams | 0 | 0 | 7.21 | 54.9% | 1.00x |
|
| 171 |
+
| **arch2_4_combined** | **1** | **2** | **6.50** | **56.8%** | **2.00x** |
|
| 172 |
+
| arch3_pipeline_registers | 0 | 0 | 7.24 | 55.1% | 1.00x |
|
| 173 |
+
| arch4_async_experts | 0 | 2 | **6.26** | **57.6%** | 1.00x |
|
| 174 |
+
| arch5_fixed_point | 0 | 0 | 6.77 | 56.2% | 1.00x |
|
| 175 |
+
|
| 176 |
+
**Key insight:** Dense delay is the bandwidth knob; expert delay is the quality
|
| 177 |
+
knob. arch4_async_experts gets the best perplexity by routing off pre-dense
|
| 178 |
+
activations (cleaner router signal) but sacrifices the bandwidth win that
|
| 179 |
+
arch2_4 achieves by also delaying the dense read.
|
| 180 |
+
|
| 181 |
+
## Inference with cflow
|
| 182 |
+
|
| 183 |
+
cflow is a Rust inference engine that reads `.cflow` (per-layer streaming) or
|
| 184 |
+
`.vflow` (vertical pipeline) weight files. Weights are stored as pre-tiled Q4
|
| 185 |
+
(128x256 tiles, ~18 KB each, sized to fit L2 cache).
|
| 186 |
+
|
| 187 |
+
```bash
|
| 188 |
+
# Build
|
| 189 |
+
cargo build --release --bin cflow-run
|
| 190 |
+
|
| 191 |
+
# Convert safetensors → .cflow
|
| 192 |
+
cargo run --release --bin cflow-convert -- \
|
| 193 |
+
--input checkpoint.safetensors \
|
| 194 |
+
--output model.cflow \
|
| 195 |
+
--model arch2_4
|
| 196 |
+
|
| 197 |
+
# Run inference
|
| 198 |
+
CFLOW_THREADS=32 ./target/release/cflow-run \
|
| 199 |
+
model.cflow 32 \
|
| 200 |
+
--prompt "Once upon a time" \
|
| 201 |
+
--tokenizer tokenizer.json \
|
| 202 |
+
--temperature 0.8
|
| 203 |
+
```
|
| 204 |
+
|
| 205 |
+
### SIMD Support
|
| 206 |
+
|
| 207 |
+
The runtime auto-detects and dispatches to the best available instruction set:
|
| 208 |
+
|
| 209 |
+
| ISA | Kernel | Notes |
|
| 210 |
+
|---|---|---|
|
| 211 |
+
| AVX-512 + VNNI | Q4×Q8 `vpdpbusd` | Best path (Ice Lake+) |
|
| 212 |
+
| AVX-512F | Q4×f32 FMA | Skylake-X+ |
|
| 213 |
+
| AVX2 + FMA | Q4×f32 FMA | Haswell+ |
|
| 214 |
+
| AVX + SSE4.1 | Q4×f32 | Sandy Bridge+ |
|
| 215 |
+
| Scalar | Q4×f32 | Fallback |
|
| 216 |
+
|
| 217 |
+
## Limitations
|
| 218 |
+
|
| 219 |
+
- **Not a general-purpose LLM.** Trained on TinyStories / FineWeb-Edu subsets at
|
| 220 |
+
10K steps — this is an architecture and runtime research artifact, not a
|
| 221 |
+
production language model.
|
| 222 |
+
- **Custom architecture.** Cannot be loaded in Hugging Face Transformers, vLLM,
|
| 223 |
+
or llama.cpp without adaptation. Requires the cflow Rust runtime or the
|
| 224 |
+
PyTorch reference in `pipeline_native/`.
|
| 225 |
+
- **CPU-only.** The runtime targets x86-64 CPUs with AVX2 or AVX-512. No GPU
|
| 226 |
+
backend.
|
| 227 |
+
- **Single-token decode optimized.** Batch/prefill throughput is not the focus.
|
| 228 |
+
|
| 229 |
+
## Thesis Scorecard
|
| 230 |
+
|
| 231 |
+
The cflow project tests 8 claims about CPU inference optimization:
|
| 232 |
+
|
| 233 |
+
| # | Claim | Result |
|
| 234 |
+
|---|---|---|
|
| 235 |
+
| 1 | Conditional expert reading (top-k only) | **Proven** |
|
| 236 |
+
| 2 | Tile-streaming L1/L2 cache locality | **Proven** (7.29x fewer L1-d misses, PMU-measured) |
|
| 237 |
+
| 3 | AVX2/AVX-512 Q4 SIMD kernels | **Proven** |
|
| 238 |
+
| 4 | Fused QKV and gate+up projections | **Proven** |
|
| 239 |
+
| 5 | Compute-order file layout | **Proven** |
|
| 240 |
+
| 6 | Software prefetch (`_mm_prefetch`) | **Refuted** (no benefit; slightly harmful) |
|
| 241 |
+
| 7 | Vertical pipeline via delayed dependencies | **Validated** (2.00x bandwidth reduction) |
|
| 242 |
+
| 8 | Stage-major disk layout readahead | **Inconclusive** (no isolated benefit; test confounded) |
|
| 243 |
+
|
| 244 |
+
## Citation
|
| 245 |
+
|
| 246 |
+
```bibtex
|
| 247 |
+
@software{poperszky2026cflow,
|
| 248 |
+
author = {Poperszky, Tom},
|
| 249 |
+
title = {cflow: CPU-First Streaming Inference for Pipeline-Native Transformers},
|
| 250 |
+
year = {2026}
|
| 251 |
+
}
|
| 252 |
+
```
|
| 253 |
+
|
| 254 |
+
## License
|
| 255 |
+
|
| 256 |
+
MIT
|