Files
ZacharyZcR 420a0720c3 docs: add simplified Chinese and Italian README, update language nav
New files:
  README.zh-CN.md — simplified Chinese (大陆用词)
  README.it.md    — Italian (the project's "mother tongue")

All four READMEs now link to each other in a consistent nav bar.
Updated zh-TW to reflect glm.c → colibri.c rename and new headers.
2026-07-19 21:12:11 +08:00

13 KiB
Raw Permalink Blame History

colibrì — motore piccolo, modello immenso

English · 简体中文 · 繁體中文 · Italiano

Motore piccolo, modello immenso. Esegui GLM-5.2 (744 miliardi di parametri, MoE) su un computer consumer con ~25 GB di RAM — in C puro, zero dipendenze, caricando gli expert dal disco in streaming.

Colibrì è un runtime MoE leggero e che preserva la qualità: tratta VRAM, RAM e disco come un'unica gerarchia di memoria gestita. Se la memoria veloce non basta il modello rallenta, ma la policy predefinita non cambia mai silenziosamente la precisione del modello né la semantica del router.

$ ./coli chat
  🐦 colibrì v1.0 — GLM-5.2 · 744B MoE · int4 · streaming CPU
  ✓ ready in 32s · resident 9.9 GB
   ciao!
  ◆ Ciao! 😊 Come posso aiutarti oggi?

Guardalo in azione

dashboard web di colibrì — metriche live, pannello hardware, livelli degli expert

La dashboard web (./coli web): un modello da 744B a 4 tok/s, TTFT 1.6 s, disco 0 — residenza completa degli expert su 6× RTX 5090, con metriche token in tempo reale, breakdown dei tempi per turno, la barra dei livelli VRAM/RAM/disco e il mini-cervello live nell'angolo.

la pagina Brain — 19.456 expert come una corteccia vivente

La pagina Brain: tutti i 19.456 expert come una corteccia vivente — il colore indica il livello di archiviazione, la luminosità il calore di routing, e ogni expert instradato in un turno lampeggia bianco. Passando il cursore si vede l'affinità tematica misurata dell'expert.

la pagina Atlas — l'atlante misurato degli expert come una galassia 3D

La pagina Atlas: l'atlante misurato degli expert come una galassia 3D — 13.260 expert caratterizzati, 1.041 specialisti replicabili che si raggruppano per argomento (poesia, legge, cinese, SQL…). La posizione deriva dall'affinità di routing misurata, non da un embedding appreso. Trascinare per ruotare.

L'idea

Un modello Mixture-of-Experts da 744B attiva solo ~40B parametri per token — e solo ~11 GB di quelli cambiano da un token all'altro (gli expert instradati):

solo ~5.4% dei parametri è attivo per token

Il modello non ha bisogno di stare in memoria veloce — ha bisogno di essere piazzato:

  • la parte densa (attenzione, expert condivisi, embedding — ~17B parametri) resta residente in RAM a int4 (~9.9 GB);
  • i 19.456 expert instradati (75 layer MoE × 256 + la testa MTP, ~19 MB ciascuno a int4) stanno su disco (~370 GB) e vengono caricati on demand in streaming, con una cache LRU per layer, un hot-store pinnato che impara, e un livello VRAM opzionale.

Il motore è un singolo file C (c/colibri.c) più header piccoli. Niente BLAS, niente Python a runtime, niente GPU obbligatoria.

Come funziona

Il percorso di ogni token

instrada → unione → piazza → sovrapponi → impara

Ogni layer di ogni token percorre gli stessi cinque passi. L'obiettivo progettuale è che il piazzamento decide solo la velocità — le decisioni del router e la precisione dei pesi sono identiche sia che un expert risponda dalla VRAM sia dal disco.

Una gerarchia di memoria, non un requisito di memoria

residenza expert a tre livelli: VRAM / RAM / NVMe

Lo stesso motore copre l'intero spettro: su un portatile da 25 GB tutto viene caricato dal disco in streaming (lento, ma corretto); su un host grande l'intero set di expert diventa residente (CUDA_EXPERT_GB=auto PIN_GB=all) e il disco esce completamente dal percorso di decode. Tra i livelli c'è una cache che impara: il motore registra quali expert il tuo carico di lavoro instrada (.coli_usage, aggiornato a ogni turno) e fissa automaticamente i più caldi — colibrì diventa letteralmente più veloce man mano che lo usi. Sugli host multi-socket, COLI_NUMA=1 interlaccia i pesi residenti tra i controller di memoria (#82).

Mai aspettare il disco due volte

I miss nella cache costano caro, quindi il motore investe la maggior parte della sua astuzia per evitarli e sovrapporli: le tre matrici di ogni expert sono memorizzate contigue e lette con un unico pread; un pool I/O asincrono limitato (PIPE=1, attivo per default) carica gli expert mancanti mentre quelli residenti calcolano; le posizioni in batch leggono ogni expert unico una sola volta (batch-union); un thread di lookahead del router (PILOT=1) fa il prefetch degli expert del layer successivo — il routing è misurabilmente prevedibile al 71.6% un layer in anticipo. Sulle GPU, la pipeline residente (COLI_CUDA_PIPE=2) mantiene il flusso residuo on-device tra i layer, così il loop CPU degli expert procede senza interruzioni; su Apple Silicon un backend Metal sperimentale esegue la matmul batch degli expert sulla GPU a memoria unificata.

Modello fedele, stato compresso

Il forward pass è validato token-esatto contro un oracle transformers (teacher-forcing 32/32). L'attenzione MLA memorizza uno stato KV compresso — 576 float/token invece di 32.768 (57× più piccolo) — e lo persiste tra i riavvii (.coli_kv): le conversazioni riaprono "calde", senza alcun re-prefill, byte-identiche a una sessione ininterrotta. L'attenzione sparsa DSA (il lightning indexer di GLM-5.2) è implementata fedelmente e validata forzando la selezione di tutte le chiavi per riprodurre esattamente l'attenzione densa.

Decodifica speculativa, onestamente

La testa MTP nativa di GLM-5.2 propone token che il modello principale verifica in un unico forward batch — 2.22.8 token/forward quando conviene. Due regole conquistate a caro prezzo sono i default: la testa MTP deve essere int8 (le teste int4 crollano al 04% di accettazione, #8), e draft e verifica devono calcolare la stessa funzioneSPEC_PIN=1 fissa entrambi sulla stessa famiglia di kernel (#163 contiene l'intera indagine forense). I draft forzati da grammatica (GRAMMAR=file.gbnf) aggiungono accettazione quasi gratuita sull'output JSON vincolato. Se la speculazione conviene dipende dalla temperatura della cache — misura, e usa DRAFT=0 quando non paga.

Cosa ottiene

velocità di decode misurata per classe hardware

Stesso motore, stesso container int4 — cambia solo dove risiedono gli expert. Punti salienti dalle tabelle benchmark complete:

  • 6× RTX 5090, residenza completa: 5.86.8 tok/s in decode, TTFT ~13 s (log dell'esperimento);
  • desktop solo-CPU da 128 GB: ~1.8 tok/s a cache calda (#200);
  • singola RTX 5070 Ti, classe laptop: 1.07 tok/s tramite la pipeline GPU-residente (#273);
  • macchina di sviluppo da 25 GB: 0.050.1 tok/s a freddo — il punto di partenza dimostrato da cui è nato il progetto, e ancora oggi la baseline onesta.

La qualità è misurata, non presunta: il costo di quantizzazione del container int4 e le ablazioni su granularità delle scale e rotazione sono in docs/benchmarks.md e #108/#81.

Per iniziare

1. Scarica il modello

Un container GLM-5.2 int4 pre-convertito è su Hugging Face — usa la versione con le teste MTP int8:

https://huggingface.co/mateogrgic/GLM-5.2-colibri-int4-with-int8-mtp

⚠️ Il mirror originale contiene teste MTP int4 → accettazione dei draft allo 0% (#8). Verifica la tua versione: ls -l <modello>/out-mtp-* — int8 (corretto) è 3527131672 / 5366238584 / 1065950496.

Oppure converti tu stesso dalla sorgente FP8 — un unico comando riprendibile che non richiede mai i 756 GB completi su disco contemporaneamente:

cd c && ./setup.sh                        # verifica gcc/OpenMP, compila, autotest
./coli convert --model /nvme/glm52_i4     # scarica e converti shard per shard (python, una tantum)

2. Esegui

COLI_MODEL=/nvme/glm52_i4 ./coli chat     # budget RAM, cache e MTP rilevati automaticamente
COLI_MODEL=/nvme/glm52_i4 ./coli plan     # mostra il piazzamento pianificato VRAM/RAM/disco
COLI_MODEL=/nvme/glm52_i4 ./coli doctor   # controllo di idoneità (sola lettura)
./coli web  --model /nvme/glm52_i4        # API + dashboard web sulla stessa porta
./coli serve --model /nvme/glm52_i4       # solo API compatibile OpenAI

Il motore a runtime è puro C — python si usa solo per il convertitore (una tantum) e per il gateway API opzionale.

3. Approfondisci

argomento documento
Benchmark, dati dalla comunità, misurazioni di qualità docs/benchmarks.md
Parametri di tuning, policy, cache che impara, prefetch docs/tuning.md
Build nativa su Windows 11 (con CUDA DLL) docs/windows.md
Backend CUDA, livello expert in VRAM, residenza completa docs/cuda.md
Backend Metal per Apple Silicon docs/metal.md
API compatibile OpenAI, KV slot, dashboard web docs/api.md
Draft forzati da grammatica (output strutturato) docs/grammar-draft.md
Inventario delle variabili d'ambiente docs/ENVIRONMENT.md

Sostenere il progetto

colibrì è nato come progetto di una sola persona su un portatile con 12 core e 25 GB di RAM; oggi i suoi numeri arrivano da una comunità di macchine reali. Se ti è utile:

  • metti una stella al repository e condividilo;
  • 🐛 apri issue con i numeri di benchmark del tuo hardware — i datapoint fanno avanzare questo progetto più di qualsiasi altra cosa;
  • 💬 contattaci via GitHub issues per sponsorizzare lo sviluppo o donare hardware.

Struttura del repository

Makefile                  punto d'ingresso root per build/check
c/
├── colibri.c             motore principale
├── quant.h               kernel matmul quantizzati (SIMD multi-architettura)
├── sample.h              campionamento, RNG, set di stop
├── kv_persist.h          persistenza KV su disco (.coli_kv)
├── telemetry.h           protocollo dashboard, statistiche, usage
├── st.h, tok.h, json.h   header di runtime
├── backend_cuda.*        livello CUDA opzionale
├── Makefile              build e check locali
├── coli                  CLI utente
├── openai_server.py      gateway HTTP compatibile OpenAI
├── setup.sh              setup locale in un solo comando
├── tools/                conversione offline, fixture e benchmark
├── scripts/              helper per conversioni lunghe
└── tests/                test C e Python senza dipendenze
web/                      UI browser (puro client API OpenAI)
desktop/                  shell desktop Tauri v2 che racchiude la web UI
docs/                     documentazione di riferimento, esperimenti, media

Il percorso a runtime resta intenzionalmente piatto e leggibile: colibri.c più i suoi header. Dalla radice del repository, make, make check e make clean delegano al Makefile del motore.

Perché "colibrì"

Il colibrì pesa pochi grammi, sta sospeso nel vuoto e visita un migliaio di fiori al giorno. Questo motore tiene in vita un gigante da 744 miliardi di parametri con le razioni di un colibrì: 25 GB di RAM, dodici core CPU e tanta pazienza col disco.

Il nome è rimasto in italiano perché questa è la lingua in cui è stato scritto il primo prototipo — i commenti nel codice lo testimoniano ancora.

Licenza

Apache 2.0. I pesi di GLM-5.2 sono rilasciati da Z.ai sotto licenza MIT.