GGUF2BIN Custom C99 runtime: GGUF → G2BX → inference (Qwen3 / Qwen2 / Llama).

3
calendar_today agoschedule5 min read

gguf2bin2 https://github.com/AnonymoDGH/gguf2bin

English | Español

C99 LLM runtime for low-RAM machines — GGUF → G2BX (own format) → inference.
Weights are memory-mapped: your real RAM budget is KV cache + activations + tokenizer, not the model file.

C99 AVX2 Vulkan RAM

Runs a 3B model on 145 MB of RAM and a large model on a 2 GB machine (--swap: KV backed on disk, footprint ≈ 37 MB).


⚡ Speed

Measured on Intel i5-6200U · 2C/4T · DDR3L dual-channel (~9.4 GB/s bus ceiling).
Sustained decode with --fast (high priority + OpenMP + quantized KV).

Model Weights (mmap) Runtime RAM decode prefill
Qwen2.5-3B Q4_0 1992 MB 145 MB 4.3 7.8
Qwen3-0.6B Q4_0 319 MB 511 MB 25.0 / 40.1 (--mv 0.5) / 39.2 (--mv 1.0) 47.9
LFM2.5-1.2B Q4_0S 567 MB 631 MB 15.7 17.9
Llama-3.2-1B F16 804 MB 644 MB 13.8
Llama-3.2-1B Q4_0S_PSY 737 MB 644 MB 14.7 / 30.6 (--mv 0.5)
SmolLM2-135M Q4_0 72 MB 40 MB 59.5

Measured 2026-08-31 on i5-6200U with bench -n 32 (min3). --mv 0.5 Swapeculative + fallback TLS buf → Qwen3 25.0→40.1 tok/s (+60%), Llama Q4_0S_PSY 14.7→30.6 (+108%). --psy (2 scales/256, 132B) gives better ppl than Q4_0S at same speed. At ~25 tok/s decode pinned to DDR3L ~9 GB/s; prefill hits compute ~27 GMAC/s.

🚀 Quick start

make            # Linux / MinGW · OpenMP + AVX2 recommended
make test       # smoke test on a synthetic model

# Pack a GGUF once, run forever
./gguf2bin2 pack Qwen3-0.6B-Q8_0.gguf qwen.g2bx --q4
./gguf2bin2 chat qwen.g2bx --no-think --fast

--threads N picks OpenMP threads; physical cores is the sweet spot.

🧠 RAM knobs

Knob Effect
--q8-kv KV cache F32→Q8_0: ~3.8× less RAM (94 % greedy argmax agreement)
-c N Context sizes to your session, not the model's 262k max
--max-ram MB Auto: enables Q8 KV first, then halves context until it fits
--swap [PATH] KV cache backed on disk → 37 MB heap even for big models
$ gguf2bin2 run qwen.g2bx "Hello" --max-ram 2048   # ideal for 2 GB machines

What counts against a 2 GB budget?

| Component | Counts? | Fix |
|---|:-:|---|
| Weights (mmap page cache) | ❌ evictable | — |
| KV cache | ✅ | --q8-kv, -c N, --swap |
| Buffers / activations | ✅ small | — |
| Tokenizer (~250k vocab) | ✅ ~30–60 MB | — |

🎛 CLI

gguf2bin2 pack model.gguf out.g2bx [--q4]     # GGUF → G2BX (--q4: half the bytes)
gguf2bin2 info model.g2bx                     # slots, geometry, types
gguf2bin2 run m.g2bx "prompt" [-n N] [-t T] [--bos] [--gpu]
gguf2bin2 chat m.g2bx [--no-think] [--fast] [--swap]
gguf2bin2 bench m.g2bx [-n 32] [--prefill 256]
gguf2bin2 ppl m.g2bx -f text.txt              # quality harness (perplexity)
gguf2bin2 vkinfo                              # Vulkan probe

Sampling: quickselect top-k O(n) + Gumbel-max + xorshift64* reproducible via --seed.

🎮 Dual band CPU+GPU (--gpu)

The head GEMV (vocab×dim, the heaviest layer) gets split between CPU and GPU with automatic calibration:

[gpu] worker ready
[gpu] dual band: cpu=[0..44855) gpu=[44855..65536)  tc=6.1ms tg=13.1ms
  • Vulkan worker in a child process — if the driver crashes or hangs, the runtime falls back to CPU-only without interrupting generation.
  • Vulkan loader bypass: loads the ICD directly from DriverStore (useful on systems with a broken Khronos\Vulkan\Drivers registry).
  • Automatic optimal split: gpu = vocab·tc/(tc+tg) measured on the first token; if the GPU is >4× slower than the CPU it shuts itself off.
  • Supports Q4_0 and Q4_0S heads. Bit-identical output vs the CPU path (greedy).

⚠️ On hardware where the iGPU shares the RAM bus with the CPU (HD 520 + DDR3L) there is no net gain — calibration detects it and disables itself. The real payoff comes with a dGPU with dedicated VRAM.

📐 Quality

Perplexity (internal corpus, SmolLM2-135M-Instruct): uniform Q4_0 = 73.7 (broken),
native Q4_K_M = 48.7, Q6_K = 48.0, Q8_0 = 48.0. Native K-quants keep Q8_0-level
quality within 1.4 % while running faster than uniform Q4_0.

Included numerical validation: make kvtest (F32 vs Q8 KV), tools/prefilltest
(bit-exact batched prefill), tools/qkcheck (46/46 K-quant kernels).

📦 G2BX format & supported types ``` G2BX | ver:u16 | arch:u8 | flags:u8 | ModelCfg | n_slots:u32 | Slot[] | data[] 64B-aligned | tokenizer Slot: role:u8 layer:u16 type:u8 nbytes:u32 off:u64 ``` | Type | Load | Fused matmul | |------|------|--------------| | F32 / F16 | yes (pack→Q4_0 if weight) | F32 path / dequant | | Q4_0 / Q4_1 / Q5_0 | yes | AVX2 fused | | Q8_0 | yes | AVX2 fused | | Q4_0S (own, fp16 shared scale /256) | yes | AVX2 batched | | Q2_K … Q6_K | yes (dequant) | AVX2 fused (Q4_K/Q6_K), scalar rest | | IQ* / Q8_K | partial | — |
🗂 Project layout ``` include/g2b.h common API src/l1_gguf.c GGUF parser (mmap) src/l2_codec.c fused dequant + matmul (AVX2) src/l3_math.c rmsnorm, rope, silu, softmax AVX2 src/l4_gbin.c G2BX packer (generic per-architecture read_cfg) src/l5_model.c load + forward + Q8 KV + RAM budget + GQA-major attention src/l6_token.c BPE tokenizer src/main.c CLI (quickselect/Gumbel sampling, chat with context compaction) src/l7_vulkan.c dual band GPU backend (child-process worker, crash-proof) shaders/ compute shaders (Q4_0/Q4_0S GEMV) tools/ kvtest · prefilltest · exptest · qkcheck · mmbench · dump_gguf.py docs/RESEARCH.md research notes and performance roadmap ```
📜 Changelog #### v4.7 — Q4_0S_PSY (psicoacústico) + fallback TLS - **Q4_0S_PSY**: 2 escalas fp16 por 256 (132B vs 130B) — baja 128 + alta 128, como MP3. `pack --psy` → +6% speed y mejor ppl que Q4_0S. Llama-3.2-1B 14.7 tok/s (PSY) → 30.6 con `--mv 0.5` (+108%). Fallback IQ ahora TLS buf → qwen38 no hace malloc por fila. #### v4.6 — Swapeculative MV Triple Band - **--mv 0.0..1.0**: tunable skip of FFN (dense) / SSM delta (hybrid) via hash + 2-bit predictor. `25.0 → 40.1 tok/s (+60%)` on Qwen3-0.6B Q4_0 with `--mv 0.5`, `39.2` with `--mv 1.0` on i5-6200U. Quality tradeoff as expected — use 0.3-0.5 for speed, 0 for quality. Works on all archs (Qwen3/Llama/LFM2/Qwen35). #### v4.5 - Batched (prefill) kernel with deferred accumulation: same treatment as the decode kernel. Qwen2.5-3B prefill 4.3 → 7.8 tok/s (+81 %), bit-exact (`tools/prefilltest`). Sets the stage for speculative verification. - **Dual band CPU+GPU head GEMV**: Vulkan worker in a child process (crash-proof), loader bypass loading the ICD straight from DriverStore, automatic split calibration with self-shutdown when the GPU doesn't help. Heads Q4_0/Q4_0S, bit-identical output. #### v4.4 - **--drop N (ShortGPT)**: measures per-block Block Influence during a quick calibration and skips the N least influential blocks. On LFM2.5-1.2B it doesn't pay off (min BI 0.106). #### v4.3 - Decode Q4_0 kernel with deferred accumulation: one hsum per row instead of one per block. Qwen2.5-3B 3.1 → 4.3 tok/s (2.9× vs v3.5); Qwen3-0.6B +10 %. - Q5_0 end-to-end (fused AVX2 kernel with high-bits LUT). - Measured quality table (`ppl` command). #### v4.2 - Fused AVX2 kernels for Q4_K and Q6_K (`maddubs` + m·Σx correction term). Before, any K-quant pack fell to the 2–5× slower fallback. Validated byte-by-byte with `tools/qkcheck`. - `ppl` command; min-of-3 bench (thermal throttling lies). #### v4.1 - K-quants fixed against official ggml (`deq_q3_K/q4_K/q5_K` broken since v3.4: half the tensor unwritten + wrong scale interleave). - Batched prefill (B=8) bit-exact; geometry validation at load; persistent Q8 activation scratch (−210 malloc/free per token). #### v4.0 - Prefill without logits (only the last token computes vocab×dim): prefill 1.32×. - GQA-major attention: each K/V row dequantized once per head group. - softmax/silu AVX2 with fast exp (rel err < 2e-7); rmsnorm fix for non-multiple-of-32 tails. - New sampling: O(n) quickselect top-k, Gumbel-max, xorshift64\*, reproducible `--seed`. - GGUF via mmap; long-chat context compaction. #### v3.x - Q4_0 AVX2 (2 blocks/iter, ILP), AVX2 attention, full K-quant dequant. - Q8_0 KV cache (`--q8-kv`), effective context, RAM budget (`--max-ram`), disk swap. - LLaMA RoPE fix (−2.0/head_dim step) and NEOX vs LLaMA: the historical root of corrupt output.
🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

The Sovereign Vault — A Comprehensive Guide to Protocol-Driven AI

Ken W. Algerverified - Jun 4

Your Backup Data Knows More Than You Think. HYCU aiR Is Finally Asking It the Right Questions.

Tom Smithverified - May 14

I Wrote a Script to Fix Audible's Unreadable PDF Filenames

snapsynapseverified - Apr 20

Unmasking Inference-Time Backdoors in GGUF Chat Templates

alessandro_pignati - Mar 2

The 3-Row Snapshot: Privacy-Preserving Inference

Pocket Portfolio - Feb 26
chevron_left
126 Points3 Badges
1Posts
0Comments
# Hi there, I'm P1bub ?

Welcome to my profile! Here you can find information about my projects, con... Show more

Related Jobs

View all jobs →

Commenters (This Week)

3 comments
1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!