colibrì: pure-C GLM-5.2 (744B MoE) engine with disk-streamed experts

Engine (c/glm.c): MLA attention with compressed KV, sigmoid noaux_tc router,
int8/int4/int2 quant kernels (AVX2), per-layer LRU expert cache + pinned
hot-store, batch-union MoE, native MTP speculative decoding (lossless),
multi-stop + official chat template, RAM auto-budget from MemAvailable.
Tokenizer: byte-level BPE in C. Tooling: coli CLI, disk-safe FP8→int4
converter, tiny-random oracle validation (TF 32/32, greedy 20/20).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
JustVugg
2026-07-05 20:52:05 +02:00
parent a6deef8e44
commit 1ae22a6135
32 changed files with 4440 additions and 1 deletions
+97
View File
@@ -0,0 +1,97 @@
"""
Stadio 0 - Cost model + benchmark del disco per lo streaming degli expert MoE.
Domanda: e' FISICAMENTE possibile fare streaming degli expert da disco
e generare a velocita' usabile, su QUESTA macchina?
Due numeri che servono:
1. Banda effettiva del disco in lettura RANDOM, a blocchi grossi quanto un expert.
2. Quanti byte/token dobbiamo leggere -> da cui il tetto di token/sec.
Nessun modello richiesto. Gira in secondi.
"""
import os, sys, time, mmap, random, argparse
MB = 1024 * 1024
GB = 1024 * MB
def bench_disk(path_dir, expert_mb=12.0, total_mb=2048, n_reads=200):
"""Crea un file, poi misura lettura sequenziale e random a chunk = un expert."""
os.makedirs(path_dir, exist_ok=True)
fpath = os.path.join(path_dir, "_bench.bin")
chunk = int(expert_mb * MB)
total = int(total_mb * MB)
total = (total // chunk) * chunk
n_chunks = total // chunk
# scrittura
t = time.time()
with open(fpath, "wb") as f:
buf = os.urandom(chunk)
for _ in range(n_chunks):
f.write(buf)
f.flush(); os.fsync(f.fileno())
write_bw = total / (time.time() - t) / GB
# prova a buttare via la page cache (best effort, serve permessi su Linux nativo)
try:
os.system("sync")
with open("/proc/sys/vm/drop_caches", "w") as c:
c.write("3")
except Exception:
pass # su /mnt/c o senza root non si puo': il numero sara' ottimistico
f = open(fpath, "rb")
mm = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ)
# random reads a chunk di un expert
idxs = [random.randrange(n_chunks) for _ in range(n_reads)]
s = 0
t = time.time()
for i in idxs:
off = i * chunk
s += mm[off] # tocca la prima pagina
s += mm[off + chunk - 1] # e l'ultima -> forza il caricamento del range
_ = bytes(mm[off:off + chunk]) # legge davvero l'intero expert
rand_bw = (n_reads * chunk) / (time.time() - t) / GB
mm.close(); f.close()
os.remove(fpath)
return write_bw, rand_bw
def cost_model(name, n_layers, n_active, expert_mb, disk_bw_gbs, ram_resident_gb):
"""Stampa il tetto di token/sec in funzione dell'hit-rate della cache."""
bytes_cold = n_layers * n_active * expert_mb / 1024 # GB letti per token se 0 cache
print(f"\n--- {name} ---")
print(f" layer={n_layers} expert_attivi/layer={n_active} expert={expert_mb:.1f} MB")
print(f" parte densa residente in RAM stimata: ~{ram_resident_gb:.1f} GB")
print(f" byte da streammare per token (cache fredda): {bytes_cold*1024:.0f} MB")
print(f" tetto token/sec @ banda {disk_bw_gbs:.2f} GB/s, al variare dell'hit-rate cache:")
for hit in (0.0, 0.5, 0.8, 0.9, 0.95, 0.99):
eff = bytes_cold * (1 - hit)
tps = disk_bw_gbs / eff if eff > 0 else float("inf")
print(f" hit {hit*100:5.1f}% -> {tps:6.2f} tok/s")
if __name__ == "__main__":
ap = argparse.ArgumentParser()
ap.add_argument("--dir", default=".", help="cartella su cui benchmarkare il disco")
ap.add_argument("--expert-mb", type=float, default=12.0)
args = ap.parse_args()
print(f"Benchmark disco su: {os.path.abspath(args.dir)} (chunk={args.expert_mb} MB)")
wbw, rbw = bench_disk(args.dir, expert_mb=args.expert_mb)
print(f" scrittura seq : {wbw:.2f} GB/s")
print(f" lettura random: {rbw:.2f} GB/s <-- numero che conta per lo streaming")
# Scenari. expert_mb a Q4 ~ (hidden*inter*3)*0.5B.
# OLMoE 1B-7B: 16 layer, 8 attivi, hidden 2048 inter 1024 -> ~3 MB Q4
cost_model("OLMoE 1B-7B (piccolo, lo useremo allo Stadio 1)",
n_layers=16, n_active=8, expert_mb=3.0,
disk_bw_gbs=rbw, ram_resident_gb=1.0)
# DeepSeek-V3/V4 class: ~60 layer MoE, 8 attivi, expert ~6 MB Q2
cost_model("DeepSeek/GLM class @ Q2 (il sogno finale)",
n_layers=60, n_active=8, expert_mb=6.0,
disk_bw_gbs=rbw, ram_resident_gb=10.0)