colibrì: движок GLM-5.2 на 744B параметров в чистом C без зависимостей

· 2 мин чтения
llm inference quantization local-first open-source
📂 Исходный код на GitHub

Чистый C, ноль зависимостей: движок для локального запуска GLM-5.2 (744B MoE) стримингом экспертов с диска и int4-квантованием.

colibrì: движок GLM-5.2 на 744B параметров в чистом C без зависимостей

colibrì — это inference-движок на чистом C (~2400 строк в одном файле), который запускает модель GLM-5.2 (744B параметров, Mixture-of-Experts) на обычной машине с ~25 ГБ RAM. Никакого BLAS, никакого Python в рантайме, никакого GPU по умолчанию. Секрет в том, чтобы стримить экспертов с диска по требованию.

Главная идея

Модель на 744B параметров активирует лишь ~40B на каждый токен, и только ~11 ГБ из них меняются от токена к токену (это маршрутизируемые эксперты). Отсюда стратегия:

  • Dense-часть (attention, shared experts, embeddings — ~17B параметров) живёт резидентно в RAM в int4 (~9.9 ГБ);
  • 21 504 маршрутизируемых эксперта (75 MoE-слоёв × 256 + MTP-head, ~19 МБ каждый в int4) лежат на диске (~370 ГБ) и стримятся по требованию через LRU-кэш на каждый слой, опциональный hot-store и OS page cache как бесплатный L2.

Движок — один C-файл c/glm.c плюс небольшие заголовки. Требования: gcc с OpenMP, AVX2, от 16 ГБ RAM и ~370 ГБ int4-модели на локальном NVMe.

Что реализовано

  • Точный forward GLM-5.2 (glm_moe_dsa) — валидирован побайтово против transformers oracle (teacher-forcing 32/32, greedy 20/20).
  • MLA attention с сжатым KV-cache: 576 float на токен вместо 32 768 (в 57× меньше — у GLM-5.2 64 головы и нет GQA).
  • DeepSeek-V3-style sigmoid router, shared expert, первые 3 dense-слоя.
  • Native MTP speculative decoding — собственная multi-token-prediction head GLM-5.2 (слой 78) генерит черновые токены, которые основная модель верифицирует одним батчем. Head обязан быть int8: при int4 acceptance падает до 0–4%, при int8 — 39–59%, 2.2–2.8 токена/forward. Без потерь в точной арифметике.
  • Grammar-forced drafts (GRAMMAR=file.gbnf) — для JSON/NDJSON, function calling и structured extraction грамматика сама служит источником драфтов: везде, где допускается ровно один легальный байт (скобки, кавычки, имена ключей), этот фрагмент инжектируется как pre-accepted draft с ~1.0 acceptance.
  • Целочисленные dot-ядра (Q8_0-style int8 activations, AVX2 maddubs): int8-матрицы в 1.4–2.5× быстрее (119 GFLOP/s).
  • MLA weight absorption (трюк DeepSeek) для decode: query поглощает kv_b, контекст проецируется после attention.
  • Async readahead экспертов: пока умножается один блок, ядро уже читает следующий (WILLNEED).
  • DSA sparse attention — индексер GLM-5.2: top-2048 causal key selection на слой.
  • KV-cache persistence — разговоры открываются тёплыми между перезапусками движка: serve-режим дописывает сжатый MLA KV в .coli_kv после каждого хода (~182 КБ/токен, crash-safe) и возобновляет при старте без re-prefill. Валидировано побайтово идентичным с непрерывной сессией.
  • Router-lookahead prefetch (PILOT=1, экспериментально) — маршрутизация следующего слоя предсказуема на 71.6% из пост-attention состояния текущего; отдельный I/O-поток префетчит тех экспертов, пока текущий слой считается.
  • Byte-level BPE tokenizer на C (GPT-2-style, 320k merges).

Честные цифры

На dev-машине автора (WSL2, 12 ядер, 25 ГБ RAM, NVMe через VHDX, ~1 ГБ/с):

Метрика Значение
Модель на диске (int4) ~370 ГБ
Резидентная RAM (dense, int4) 9.9 ГБ
Время загрузки ~30 с
Пиковый RSS во время чата ~20 ГБ (авто-cap)
Холодная стоимость decode ~11 ГБ чтений/токен (75 слоёв × 8 экспертов)
MTP-спекуляция (int8 head) 2.2–2.8 токена/forward

Это не быстро — ~0.05–0.1 tok/s на холодном старте. Но это 744B frontier-модель, отвечающая корректно на машине дешевле одного кулера H100. Тёплый кэш, закреплённые hot-эксперты и MTP заметно снижают латентность.

На лучшем железе комьюнити измеряло: M5 Max 128 ГБ с Metal — 2.06 tok/s, EPYC 7443 с 430 ГБ RAM — 1.00 tok/s (98% hit, диск устранён), 6× RTX 5090 с полным размещением — 6.84 tok/s decode.

Обучающийся кэш

Движок записывает, к каким экспертам реальная нагрузка обращается (.coli_usage рядом с моделью), и при старте автоматически закрепляет самые горячие в свободной RAM. colibrì буквально ускоряется, чем больше им пользуешься. Опциональная живая адаптация тиров (--repin N) заменяет холодые закреплённые эксперты на более горячие по затухающей session heat map.

Эксплуатация

cd c
./setup.sh                                  # проверяет gcc/OpenMP, собирает, self-test
./coli convert --model /nvme/glm52_i4       # FP8→int4, пошардово, возобновляемо
COLI_MODEL=/nvme/glm52_i4 ./coli chat       # RAM, кэш, MTP — всё определяется автоматически

Готовая int4-модель с int8 MTP-head доступна на Hugging Face — это пропускает шаг конвертации:

COLI_MODEL=/path/to/GLM-5.2-colibri-int4-with-int8-mtp ./coli chat

Важно: MTP-head обязан быть int8. Оригинальное зеркало с int4-head даёт 0% draft acceptance — спекуляция молча не включается.

OpenAI-совместимый API и веб-дашборд

coli serve держит один процесс с моделью и предоставляет text-only OpenAI-совместимый HTTP API: /v1/chat/completions, SSE streaming, изоляция KV-контекстов через cache_slot (до 16 независимых последовательностей), очередь FIFO с HTTP 429 при перегрузке.

Одна команда поднимает и API, и веб-консоль на одном порту:

./coli web --model <model-dir>

Дашборд показывает живые метрики токенов, панель железа и полосу тиров экспертов, а страница Brain отображает все 19 456 экспертов как живую кору: цвет = тир хранения, яркость = routing heat, эксперты текущего хода вспыхивают белым.

Бэкенды

  • CUDA (опционально) — резидентные тензоры на GPU, streaming-эксперты остаются на CPU. На 6× RTX 5090 с авто-размещением всех экспертов — 6.00 tok/s decode при 100% hit.
  • Metal (Apple Silicon, экспериментально) — batched SwiGLU, fused decode attention и prefill GEMM на GPU. На M4 Max 128 ГБ: 0.30 → 0.42 tok/s (~1.4×). Greedy-выход побайтово идентичен CPU.
  • Windows 11 native (MinGW-w64) — вся специфика платформы изолирована в compat.h, исходник движка не меняется. CUDA под Windows собирается в отдельную coli_cuda.dll, хост грузит её через LoadLibrary.

Лицензия

Apache 2.0. Веса GLM-5.2 выпущены Z.ai под MIT.

Источник: https://github.com/JustVugg/colibri