Show HN: 如何在我的低配置电脑上运行 GLM-5.2
Show HN: Show HN:如何在我的低配置电脑上运行 GLM 5.2
colibrì v1.0 引擎以纯 C 实现、零运行时依赖,可在约 25 GB RAM 的消费级电脑上运行 744B 参数的 GLM-5.2 MoE 模型。模型经 int4 量化后磁盘占用约 370 GB,常驻内存仅 9.9 GB,通过流式加载磁盘专家实现推理。冷解码速度约
这个单C文件项目让744B的MoE模型在25GB内存的笔记本上跑了起来,虽然慢,但证明了消费级硬件也能把前沿模型‘盘活’,做本地推理的极客值得看看。
微型引擎,巨型模型。在约 25 GB 内存的消费级机器上运行 GLM-5.2(744B 参数 MoE)——纯 C 实现,零依赖,通过从磁盘流式加载专家。
Colibrì 是一个轻量级、保持质量的 MoE 运行时,它将 VRAM、RAM 和存储视为一个统一管理的内存层级。快速内存不足可能会降低速度,但默认策略绝不会悄悄改变模型精度或路由器语义。
$ ./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?
观看运行效果
Web 仪表盘(./coli web):一个 744B 模型在 6× RTX 5090 上以端到端 4+ tok/s 的速度作答——带有实时 token 指标、硬件面板,以及 VRAM/RAM/磁盘专家层级。
Brain 页面:全部 19,456 个专家构成一个鲜活的皮层——颜色代表存储层级,亮度代表路由热度,每一轮中被路由到的专家都会闪白光。悬停可显示该专家的实测主题亲和度。
目录
思路
一个 744B 的混合专家(MoE)模型每个 token 只激活约 40B 参数——而其中只有约 11 GB 会随 token 变化(即被路由的专家)。因此:
- 稠密部分(注意力、共享专家、嵌入向量——
17B 参数)以 int4 精度常驻内存(9.9 GB); - 21,504 个被路由的专家(75 个 MoE 层 × 256 个专家 + MTP 头,int4 下每个
19 MB)存放在磁盘上(370 GB),并按需流式加载,配有逐层 LRU 缓存、可选的固定热存储,以及作为免费 L2 的操作系统页缓存。
该引擎是一个单独的 C 文件(c/glm.c,约 2,400 行)加上一些小型头文件。没有 BLAS,运行时没有 Python,不需要 GPU(存在一个可选的 CUDA 层级用于固定专家——见下文)。
已实现的功能
- 忠实还原的 GLM-5.2(
glm_moe_dsa)前向传播——已针对transformers参考实现进行 token 级精确验证(在一个采用真实架构的小型随机模型上,teacher-forcing 32/32,贪心解码 20/20)。 - MLA 注意力(q/kv-LoRA,交错式部分 RoPE)配合 压缩 KV-cache:每 token 576 个浮点数,而非 32,768 个(缩小 57 倍——GLM-5.2 有 64 个注意力头且不使用 GQA)。
- DeepSeek-V3 风格的 sigmoid 路由器(noaux_tc、routed_scaling_factor),共享专家,前 3 层为稠密层。
- 原生 MTP 投机解码——GLM-5.2 自带的多 token 预测头(第 78 层)起草 token,由主模型在一次批量前向中验证。该预测头必须是 int8(转换器默认如此):在 int4 下,草稿接受率暴跌至 0–4%,投机解码根本不会启用;在 int8 下接受率为 39–59%,每次前向 2.2–2.8 个 token(社区实测,#8)。在精确算术下是无损的——但在实践中与非投机贪心解码并非逐字节一致(#100)。这并非 MTP 独有:colibrì 的量化整数 kernel 依赖形状,因此任何批量(S>1)或 GPU 前向的舍入方式都与单 token 路径略有不同,而 int4 的 GLM-5.2 距离 argmax 平局足够近,这种舍入变化就可能翻转某个 token。MTP、CUDA 专家层和批量 prefill 是触发同一敏感性的三种不同方式(社区在 #100 中确认:仅更换 kernel 家族就会在 3/5 的提示词上使贪心输出分叉,且零投机解码)。每个输出的 token 仍然是某次有效前向的 argmax——续写内容依然正确——只是不再是同一个流。若要逐字节精确复现:
DRAFT=0(无投机解码),再加上IDOT=0 COLI_CUDA=0(如果你还想要 kernel 家族/GPU 无关性)。在采样下,拒绝采样可保持分布正确。来自同一测量的诚实提醒:在冷缓存下,每个被验证的草稿都会路由到额外的专家(约 660 → 约 1100 次专家加载/token),因此在缓存/固定预热之前,投机解码可能是净时间损失。 - 语法强制的推测草稿(
GRAMMAR=file.gbnf,#48)——在受限输出工作负载(JSON/NDJSON、函数调用、结构化抽取)上,语法本身就是第三个草稿来源:只要语法恰好允许一个合法字节(花括号、引号、键名、枚举体),该强制片段就会被 tokenize 并作为预先接受的草稿注入,接受率约为 1.0——无需草稿头,无需查找表,而且即使搭配来自#8的 int4 MTP 头也能生效。它从不约束采样:强制片段与任何草稿一样,在同一批次并集前向中被验证,因此错误或不同步的语法无法改变输出——最坏情况只是草稿被拒绝,而一个自适应保护会在接受率低于 50% 时关闭该来源。字节级 GBNF 子集(字面量、字符类、| ( ) ? * +、注释);GRAMMAR_DRAFT=n限制每次前向的强制片段长度(默认 24)。可与DRAFT/MTP 组合,后者填充强制片段之间的自由文本空隙。完整参考——机制、实测 A/B、何时划算、先前工作:docs/grammar-draft.md。 - 真实采样——temperature + nucleus,默认值针对 int4 现实调优(0.7 / 0.90;官方的 1.0 / 0.95 会从尾部采样到量化噪声)。
- 整数点积内核(Q8_0 风格 int8 激活,AVX2
maddubs):int8 矩阵乘法快 1.4–2.5×(实测 119 GFLOP/s),int4 在批处理中快 1.8×——路由按形状由实测决定(int4 单行保持 f32:实测更慢)。 - MLA 权重吸收(DeepSeek 技巧)用于解码:无需逐 token 重建 k/v——查询吸收
kv_b,上下文在注意力之后投影。已验证精确:TF 32/32,生成 20/20,且在所有位置强制启用吸收。 - 异步专家预读:当一组专家正在做乘法运算时,内核已经在读取下一组(
WILLNEED)。 - 量化内核:int8 / packed int4 / packed int2,逐行缩放,AVX2,使用时反量化。打包已验证与 int8 容器逐位一致。
- DSA 稀疏注意力——GLM-5.2 的闪电索引器,忠实于参考
glm_moe_dsa建模:逐层 top-2048 因果键选择(完整/共享索引器层),从out-idx-*权重自动检测(--indexer转换器模式,从 FP8 仓库中提取约 189 MB)。已验证精确:强制选择保留每一个键可逐 token 复现稠密注意力。DSA=0禁用,DSA_TOPK覆盖。 - KV-cache 持久化——对话在引擎重启后热恢复:serve 模式在每一轮之后将压缩后的 MLA KV 追加到
.coli_kv(约 182 KB/token,崩溃安全),并在启动时恢复,零重新预填充。已验证与不间断会话逐字节一致。KVSAVE=0禁用。 - 路由器前瞻预取(
PILOT=1,实验性)——下一层的路由选择有 71.6% 可以从当前层注意力后的状态预测出来(实测);一个专用的 I/O 线程在当前层计算时预取这些专家。 - 批处理并集 MoE:在预填充(以及 MTP 验证)中,批次里每个唯一的专家只读取一次,并应用到所有路由到它的位置上。
- 用 C 实现的字节级 BPE 分词器(GPT-2 风格,带 Unicode 属性正则,320k 次合并)。
- 内存安全:专家缓存会在启动时根据
MemAvailable自动设定大小——一份诚实的峰值预估(工作集、KV、MTP 行、重建缓冲区),从而内核的 OOM killer 永远不会触发。 - 离线 FP8→int4 转换器(
c/tools/convert_fp8_to_int4.py):一次下载一个分片(约 5 GB),反量化(128×128 块缩放),重新量化到引擎的容器格式,删除该分片——756 GB 的 FP8 检查点永远不需要同时存在于磁盘上。可断点续传。
诚实的数字(WSL2,12 核,25 GB 内存,通过 VHDX 的 NVMe)
详细的 GPU 实验:GLM-5.2 在 6 块 RTX 5090 上——跨 VRAM+RAM 的完整专家驻留达到单请求解码 6.84 tok/s。
| 指标 | 值 |
|---|---|
| 磁盘上的模型(int4 容器) | ~370 GB |
| 常驻 RAM(稠密,int4) | 9.9 GB |
| 加载时间 | ~30 s |
| 对话期间峰值 RSS | ~20 GB(自动封顶) |
| 冷启动解码开销 | ~11 GB 磁盘读取/token(75 层 × 8 专家) |
| 磁盘上限(这台开发机的硬盘) | ~1 GB/s → 冷启动约 0.05–0.1 tok/s |
| MTP 推测(int8 头) | 实测 2.2–2.8 tok/前向(#8) |
这并不快。这是一个 744B 前沿级模型在一台比一个 H100 风扇还便宜的机器上正确作答。热缓存、固定热专家和 MTP 将有用响应的延迟大幅压低;剩下的交给磁盘的物理规律。
SSD 说明
冷启动会带来大量随机读取(约 11 GB/token),但读取并不会对 SSD 造成实质性磨损——colibrì 的流式处理是只读的。在高强度使用下真正需要担心的是:(1) 如果系统内存耗尽而产生的 swap 交换流量(写入确实会磨损硬盘——请保留一个合理的 --ram 预算;colibrì 的自动预算机制就是为了避免触发 swap 而设计的),以及 (2) 持续高温:长时间处于满负荷读取状态会让廉价硬盘发热。请监控硬盘温度和健康状态。
下载模型
一个为 colibrì 预转换好的 GLM-5.2 int4 模型已在 Hugging Face 上提供——请使用带有 int8 MTP 头的版本(matey-0 的克隆版):
⚠️ MTP 头必须是 int8。 原始镜像(jlnsrk/GLM-5.2-colibri-int4)附带的是 int4 MTP 头,会导致 0% 的草稿接受率——推测解码会悄无声息地从不生效,你也就失去了约 2× 的 MTP 杠杆。这是最常见的"为什么 MTP 卡在 0%?"报告(#8、#102)。int8 头能带来实测的 39–59% 接受率。上面 matey-0 的克隆版就是原始 int4 模型,只是三个
out-mtp-*文件已经替换为 int8——下载那个就万事大吉了。检查你手头的内容:
ls -l <model>/out-mtp-*· int8(正确):3527131672 / 5366238584 / 1065950496· int4(0% 接受率):1765523544 / 2686077736 / 536747200—— 如果你看到这些,只需从 int8 镜像中替换这三个文件。
下载该仓库,并将 COLI_MODEL 指向其目录:
COLI_MODEL=/path/to/GLM-5.2-colibri-int4-with-int8-mtp ./coli chat
这样完全跳过了 FP8 → int4 转换步骤。感谢 DatPat 提供原始镜像,以及 matey-0 提供 int8-head 克隆。
快速开始
cd c
./setup.sh # checks gcc/OpenMP, builds, self-tests
# ONE command does everything model-side: downloads GLM-5.2-FP8 shard by shard
# (never needs the full 756 GB at once), converts to the int4 container, then
# converts the MTP head for speculative decoding. Resumable at any point.
# Conversion (only) needs python with: pip install torch safetensors huggingface_hub numpy
./coli convert --model /nvme/glm52_i4 # ~400 GB free on a real ext4/NVMe path
# chat — RAM budget, expert cache and MTP are all detected automatically:
COLI_MODEL=/nvme/glm52_i4 ./coli chat
在加载模型之前,先检查计划中的存储层级:
COLI_MODEL=/nvme/glm52_i4 ./coli plan
COLI_MODEL=/nvme/glm52_i4 ./coli plan --gpu 0,1 --ram 128 --vram 48 --json
# apply the bounded plan to the normal runner
COLI_MODEL=/nvme/glm52_i4 ./coli chat --auto-tier
coli plan 只读取 safetensors 头部,并报告模型精确的稠密/专家占用、运行时 RAM 预留、安全的专家缓存上限,以及有界的 VRAM 热层。其带版本号的 JSON 输出旨在由 CLI、API 服务器、Web UI 和桌面外壳共享;它不会分配模型张量,也不会启动推理。--auto-tier 将同样的方案应用于 chat、run、serve 和基准测试。它会立即设置 RAM 预算和上下文;只有当当前的 glm 二进制文件链接了 CUDA 时,才会启用 VRAM 层级。显式标志和环境变量优先于自动值。
在加载模型之前,coli doctor 会执行一次只读的就绪检查,并说明所选的 Disk/RAM/VRAM 放置方案是否可运行:
COLI_MODEL=/nvme/glm52_i4 ./coli doctor
COLI_MODEL=/nvme/glm52_i4 ./coli doctor --gpu 0 --ram 128 --json
Doctor 会校验模型目录、配置、tokenizer、safetensors 头部、引擎可执行文件、可用 RAM、请求的 NVIDIA 设备、CUDA 链接情况,以及与 coli plan 相同的放置预算。它从不启动 glm,不读取张量数据,不导入模型框架,也不创建 CUDA 上下文。带版本号的 JSON 报告使用稳定的检查 ID,便于自动化处理。警告保持退出状态码为 0;缺少依赖项或 RAM 预估不安全时返回 1,而无效的 CLI 取值返回 2。
运行时的引擎是纯 C —— python 仅用于一次性的转换器。
Windows 11(原生,不使用 WSL)
colibrì 在 Windows 11 x86-64 上使用 MinGW-w64 原生构建并运行。该移植版本添加了一个_WIN32兼容层,位于c/compat.h其中将 POSIX I/O 映射到 Windows API(pread → ReadFile+OVERLAPPED,posix_fadvise 为空操作,对齐分配,MoveFileEx 重命名,GlobalMemoryStatusEx 内存检测)。所有平台差异都保留在compat.h中;引擎源代码保持不变。
工具链:通过 winlibs 或 MSYS2 MinGW-w64 使用 GCC。已用 GCC 16.1.0(x86_64-ucrt-posix-seh)测试。
# One-time toolchain install (pick one):
scoop install mingw-winlibs # portable, no shell needed
# or: pacman -S mingw-w64-x86_64-gcc make # via MSYS2
# Build (from c/ directory):
make glm.exe # GLM-5.2 engine (static, no DLL dependencies)
make olmoe.exe # OLMoE engine (same shims)
make iobench.exe # disk I/O benchmark
make test-c # run C tests
make test-python # run Python tests (requires python)
# AVX-VNNI: Intel Alder Lake+ (and Meteor Lake+) CPUs have a 128-bit int8
# dot-product instruction (VPDPBUSD) the engine can use for ~1.3x faster
# quantized matmul. The x86-64-v3 default (portable AVX2) compiles it out;
# build for THIS machine to enable it:
make glm.exe ARCH=native # banner prints "idot: avx-vnni"
# Verify (tiny model, 2.4 MB):
pip install torch transformers safetensors huggingface_hub
python tools/make_glm_oracle.py # generate tiny oracle
SNAP=./glm_tiny TF=1 ./glm.exe 64 16 16 # expect "32/32 positions"
# Run with real model:
SNAP=D:\glm52_i4 ./glm.exe 64 4 16 # batch inference
python coli chat --model D:\glm52_i4 # interactive chat
python coli serve --model D:\glm52_i4 # OpenAI-compatible API
预热(隔夜缓存预热):引擎的专家缓存会从你的工作负载中学习。随附的 warmup.ps1 脚本会以多样化提示词循环运行 coli run,在无人值守的情况下构建 .coli_usage 直方图,这样下一次真实会话启动时就能拥有一个规模大且准确的 hot-expert 固定。每次运行都会在干净完成时以原子方式保存使用情况。
.\warmup.ps1 -Rounds 1 -Ngen 32 # ~60-90 min, durable progress
NVIDIA GPU(可选,通过运行时 DLL):在 Windows 上,引擎使用 MinGW gcc 构建,但 CUDA 内核需要 MSVC + nvcc。分工很清晰:将 CUDA 后端构建为一个独立的 coli_cuda.dll(nvcc + MSVC),然后宿主 glm.exe 在运行时通过 LoadLibrary(c/backend_loader.c)加载它。宿主从不直接链接 cudart;如果该 DLL 不存在,引擎会无报错地回退到 CPU。
# Prerequisites: CUDA Toolkit + MSVC Build Tools (cl.exe) + nvcc on PATH.
# Build the DLL from a shell with the MSVC environment set (vcvars64.bat or
# "x64 Native Tools Command Prompt for VS"):
make cuda-dll CUDA_HOME="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.8" CUDA_ARCH=sm_120
# Build the host with the runtime loader (CUDA_DLL=1 adds -DCOLI_CUDA and
# links backend_loader.o instead of cudart):
make glm.exe CUDA_DLL=1 ARCH=native
# Run with the GPU expert tier (8 GB VRAM budget here; scale to your free VRAM):
$env:COLI_CUDA="1"; $env:COLI_GPU="0"; $env:CUDA_EXPERT_GB="8"
python coli chat --model D:\glm52_i4 --topp 0.7
该 DLL 导出 11 个 extern "C" 符号(coli_cuda_init、coli_cuda_matmul 等);backend_loader.c 在首次使用时通过 GetProcAddress 解析它们。ColiCudaTensor* 对宿主是不透明的(仅存储,从不解引用),因此 MSVC 分配的结构体跨 ABI 边界是安全的。CUDA_ARCH 必须与你的 GPU 的计算能力匹配(例如 Blackwell / RTX 50 系列对应 sm_120,Ada / RTX 40 系列对应 sm_89)。
状态:第一阶段完成(可编译、正确、静态链接)。Windows GPU 层级(运行时coli_cuda.dll通过LoadLibrary)已实现,并在 RTX 50 系列(sm_120)上验证通过。O_DIRECT(第二阶段)以及针对 transformers oracle 的全模型验证仍是独立的工作流。
兼容 OpenAI 的 API
coli serve 保持一个模型进程常驻加载,并对外暴露一个纯文本、兼容 OpenAI 的 HTTP API。该网关仅使用 Python 标准库;推理仍然在同一个无依赖的 C 引擎中运行。
cd c
COLI_MODEL=/nvme/glm52_i4 COLI_API_KEY=local-secret ./coli serve \
--host 127.0.0.1 --port 8000 --model-id glm-5.2-colibri
curl http://127.0.0.1:8000/v1/chat/completions \
-H 'Authorization: Bearer local-secret' \
-H 'Content-Type: application/json' \
-d '{
"model": "glm-5.2-colibri",
"messages": [{"role": "user", "content": "Hello"}],
"stream": true
}'
已实现的端点包括 GET /v1/models、GET /v1/models/{model}、POST /v1/chat/completions 以及旧版 POST /v1/completions。聊天与补全请求支持 JSON 响应、SSE 流式传输、用量计数、max_tokens/max_completion_tokens、temperature 以及 top_p。扩展字段 enable_thinking: true 可启用 GLM-5.2 的推理块;标准的 reasoning_effort 字段同样会启用它,除非将其设置为 none。
第一个版本刻意仅支持文本,且一次只服务一个生成请求:744B 模型常驻于单个持久进程中,因此并发的 HTTP 请求会排队,而不是加载重复的模型副本。工具、图像/音频输入、自定义停止序列、对数概率以及 token 惩罚会返回明确的错误,而不是被静默忽略。默认绑定地址为 localhost;在将服务器暴露到本机之外前,请先设置 COLI_API_KEY。
默认允许来自 Vite 开发服务器和 Tauri 本地源的浏览器访问。重复使用 --cors-origin https://your-ui.example 可允许另一个精确源,或仅在受信任的本地网络上使用 --cors-origin '*'。
该引擎拥有一个可变的 KV 上下文,因此 HTTP 生成使用有界的 FIFO 准入队列,而不是假装运行不安全的并行序列。可通过 --max-queue N(默认 8)和 --queue-timeout SECONDS(默认 300)进行配置,或使用 COLI_MAX_QUEUE / COLI_QUEUE_TIMEOUT 环境变量。饱和与超时的请求会在发送流式响应头之前收到 OpenAI 格式的 HTTP 429 错误。GET /health 会暴露 active/queued/completed/rejected 计数器,成功的生成响应会包含 x-colibri-queue-wait-ms。
隔离的 KV 上下文
coli serve --kv-slots N 最多分配 16 个独立的序列上下文。请求通过可选的整数 cache_slot 字段选择一个;普通 OpenAI 客户端会省略该字段,从而保持原有的 slot 0 行为。
{
"model": "glm-5.2-colibri",
"messages": [{"role": "user", "content": "Continue this conversation"}],
"cache_slot": 1
}
每个 slot 拥有自己的 token 历史、压缩的 MLA/DSA KV 内存、MTP 窗口以及崩溃安全的持久化文件(.coli_kv、.coli_kv.1……)。引擎仍然一次只执行一个序列;这确立了明确的 KV 归属,而不是假装多线程 HTTP 就是连续批处理。RAM 准入会为每个已配置的 slot 计入开销。使用 COLI_KV_SLOTS=N 作为等效的环境变量。从小值开始:在默认 4096 token 上下文下,每个 slot 要花费数百 MB。
实验性 Metal 后端(Apple Silicon)
在 Apple Silicon 上,解码性能受 matmul 制约,而统一内存消除了让 CUDA 的流式专家留在 CPU 上的 PCIe 拷贝开销——因此 colibrì 提供了一个可选的 Metal 后端,在 GPU 上运行 routed-expert SwiGLU(批处理,从 RAM slab 零拷贝)、融合解码注意力(整个 MLA 层在一个命令缓冲区中,S≤4)以及 prefill 的大型 GEMM。与 CPU 路径相比 token 完全一致。
cd c
make glm METAL=1 # macOS only; no Xcode needed (shader compiles at runtime)
make metal-test # standalone kernel/attention correctness vs CPU reference
COLI_METAL=1 COLI_MODEL=/path/glm52_i4 ./coli chat --ram 96
在 M4 Max(128 GB,热缓存,开启 MTP)上实测:CPU 0.30 → Metal 0.42 tok/s(约 1.4×)(最佳配置额外加上 DIRECT=1;相比这台机器首次冷启动约 3×)。关键设计要点:Metal 约 5 ms 的提交延迟使得逐 matmul 派发成为损失——所有内容都被批处理进每层少量的命令缓冲区,而常驻专家的 GPU 工作会在未命中专家的磁盘读取之前提交,从而让 I/O 与计算重叠。COLI_METAL_GEMM_MIN 用于调节 prefill GEMM 的行阈值(默认 16)。流式、缓存、MTP、DSA 以及持久化格式均未改变;任何故障下每条 GPU 路径都会按块回退到 CPU。数值计算为 dequant→f32-MAC(与 CUDA 层级相同);贪心输出与 CPU 引擎逐字节一致。
实验性常驻 CUDA 后端
colibrì 包含一个可选的 CUDA 后端,用于模型常驻张量。流式专家目前有意保留在原有的 CPU 路径上:每次使用时都把专家从 NVMe 复制到 GPU,只会把磁盘瓶颈换成 PCIe 瓶颈。常驻的量化张量会惰性上传一次并复用。
cd c
make cuda-test CUDA=1 # q8/q4/q2/f32 kernel correctness
make CUDA=1
# optional dense-path experiment (hot experts are configured below)
COLI_CUDA=1 COLI_GPU=0 CUDA_DENSE=1 SNAP=/nvme/glm52_i4 ./glm 64 4 4
要求:Linux、NVIDIA 驱动,以及位于 /usr/local/cuda 下的 CUDA Toolkit(可用 CUDA_HOME=/path/to/cuda 覆盖)。CUDA_ARCH=native 会为当前机器上的 GPU 构建;交叉编译时需显式设置架构。在仅 CPU 的二进制上请求 CUDA、设备无效或运行时不可用,都会在启动时失败,而不是静默回退。
常规的 make 构建和运行时行为保持不变。CUDA 默认仅作为专家专用加速器。CUDA_DENSE=1 还会将常驻的稠密/注意力投影张量以轮询方式分布到所选设备上;其投影占用会在专家层放置之前预留。在六块 RTX 5090 上搭配 150 GB 专家层时,一次预热后的双请求/64-token GLM-5.2 运行从 1.650 提升到 2.157 聚合 tok/s(+30.8%),同时保留了完整的专家层。在投影的稠密集合与每设备 2 GB 运行时预留能够适配目标 GPU 之前,请将此视为可选启用项。一个经过实测的 PIN 配置文件可以将其最热门的专家提升到持久化 VRAM 层,同时将其余部分保留在 RAM 中:
STATS=stats.txt SNAP=/nvme/glm52_i4 ./glm 64 4 4 # collect routing frequencies first
COLI_CUDA=1 COLI_GPU=0 CUDA_EXPERT_GB=16 \
PIN=stats.txt PIN_GB=160 SNAP=/nvme/glm52_i4 ./glm 64 4 4
# multi-GPU expert tier, 150 GB total budget across six 32 GB devices
COLI_CUDA=1 COLI_GPUS=0,1,2,3,4,5 CUDA_EXPERT_GB=150 \
CUDA_DENSE=1 PIN=stats.txt PIN_GB=300 RAM_GB=226 \
SNAP=/nvme/glm52_i4 ./glm 64 4 4
# large-RAM host: fill safe VRAM, then keep every remaining expert in RAM
COLI_CUDA=1 COLI_GPUS=0,1,2,3,4,5 CUDA_EXPERT_GB=auto \
CUDA_DENSE=1 COLI_CUDA_ATTN=1 PIN=stats.txt PIN_GB=all RAM_GB=auto \
SNAP=/nvme/glm52_i4 ./glm 64 4 4
选定的专家会在启动时上传,因此容量故障发生在推理之前,日志会报告它们确切的张量占用。在预留了预计的稠密常驻集以及每块选定设备 2 GB 的运行时余量之后,预算会根据空闲 VRAM 进行钳制。使用 COLI_GPUS 时,CUDA_EXPERT_GB 是整个设备集合的总预算;专家会被整块分配给能够容纳它们的负载最低的设备。多 GPU 运行还默认采用 PIN_FILL=1:先放置测得的热集,然后用零热度专家填充未使用的 VRAM。CUDA_RELEASE_HOST=1(多 GPU 默认值)会在成功上传后释放 RAM 副本,只有在 CUDA 之后失败时才从磁盘重新加载。将任一变量设为 0 即可恢复保守行为。当宿主后备被释放时,放置是不相交且分阶段的:先加载最热的专家前缀,上传到 VRAM 并释放,然后再将下一梯队的后缀加载到 RAM。因此 PIN_GB 描述的是合并后的排序集合,而不是重复的 RAM 和 VRAM 副本。在一台 256 GB 双路主机上,从 150 GB VRAM + 130 GB RAM 的放置改为 150 GB VRAM + 150 GB RAM 后,固定 token 重放从 1.87 提升到 2.16 tok/s(+15.7%),专家磁盘等待从 5.144s 降至 3.948s,并将预计 RAM 峰值保持在 RAM_GB=226 以下。缓存上限会自动下调(该次运行中从 54 降至 40),因此更大的固定层级不会超出进程预算。在可用 RAM 较少的主机上,请从更低的值开始。
CUDA_EXPERT_GB=auto 只会将每块选定设备填充到其测得空闲内存减去预计的稠密张量和 2 GB 运行时余量为止。PIN_GB=all 随后将所有剩余的路由专家加载到 RAM 中,在主机预算允许时消除解码时的磁盘未命中。常规的 RAM_GB 防护仍会限制每层工作缓存并拒绝不安全的预估;此模式面向专用的高内存推理主机,而不是运行其他工作负载的桌面机。在一台配备六块 RTX 5090 的专用 251 GiB 主机上,此模式选择了一个 176.7 GB VRAM 专家层级和一个 191.3 GB RAM 层级(全部 19,456 个专家常驻)。该模式还会每生成 16 个 token 就调整一次 VRAM 层级,将热 RAM 专家换入现有的 GPU 槽位。一次真实的 64-token 贪心 GLM-5.2 生成测得 6.00 tok/s 解码,高于此前 150 GB 层级的 2.20 tok/s 端到端速度;专家命中率为 100%,磁盘等待为零。提示词预填充单独报告。这是特定主机的容量结果,不是可移植的默认值。
文本模式计时将预填充与解码分开报告。解码速率从提示词 KV 构建完成后开始计算,因此可与 REPLAY 吞吐量相比较,同时不会隐藏首 token 时间。MTP 推测在 CUDA 上默认关闭,因为冷启动草稿路由会增加专家流量;显式的 DRAFT=n 仍可覆盖默认值。
在六块 RTX 5090 32 GB 显卡上运行 GLM-5.2 int4,一个 150 GB 的热优先层级在一个 64-token 的多样化提示词上维持了 0.94 token/s(专家命中率 87.8%),并在一个已预热的短提示词上达到 1.64 token/s(命中率 99.3%)。同样的容量在未按路由热度填充时仅能达到 0.29 token/s,因此配置文件质量比原始 VRAM 容量更重要。这些是单次运行的工程测量结果,不是可移植的性能保证。
当前限制:设备使用独立的上下文和同步的、由主机暂存的激活副本——目前还没有 P2P/NCCL 依赖。独立的专家组分跨设备并发执行,但单个专家并未被分片。这些内核是正确性优先的自定义内核,而非 cuBLAS/Tensor Core 内核。
若要在没有完整检查点的情况下进行可复现的后端 A/B 对比,请生成确定性的 313M 参数 glm_moe_dsa 夹具,并运行固定 token 回放:
cd c
python tools/make_glm_bench_model.py --output /nvme/colibri-bench-medium --device cuda
python tools/benchmark_cuda_fixture.py --model /nvme/colibri-bench-medium --gpu 0
该夹具使用随机权重,并非语言模型。它的存在仅仅是为了保留真实的 MLA/MoE/流式形状,并用相同的回放 token 来对比 CPU 流式、仅稠密 CUDA、CPU 热存储和 CUDA 热专家执行。
Web 界面
web/ 包含一个社区贡献的浏览器 UI(React + TypeScript,约 390 行源码,一个纯 API 客户端——它从不直接接触引擎):
cd web
npm ci && npm run dev # then point it at an OpenAI-compatible endpoint
它使用标准的 OpenAI Chat Completions 协议并支持 SSE 流式传输,因此可对接 colibrì 的 OpenAI 兼容服务器(审核中,#21)或任何其他兼容端点。不会有任何数据离开你所配置的端点。终端 coli chat 仍是一等接口。
实用调节项(环境变量或标志):--temp T token 采样温度(默认 0.7 + nucleus 0.90——针对 int4 调优;0 = 贪婪),--topp 0.7 自适应专家 top-p(减少 30–40% 磁盘占用),--ngen N 每次回答的最大 token 数(在聊天中 :more 会继续一个被截断的回答),--repin N 每输出 N 个 token 就调整 RAM/VRAM 热专家,AUTOPIN=0 禁用学习缓存的自动固定,THINK=1 启用 GLM-5.2 的推理块,DRAFT=n MTP 草稿深度,GRAMMAR=g.gbnf 用于受限 JSON/NDJSON 输出的语法强制草稿(GRAMMAR_DRAFT=n 限制强制跨度),TF=1 teacher-forcing 验证,PILOT=1 路由器前瞻磁盘预取(实验性——见下文),CAP_RAISE=0 不自动增长专家缓存。
资源策略
coli plan 报告计划中的热(VRAM)、温(RAM)和冷后备(磁盘)层级、每个放置的原因以及预期的瓶颈。默认的 --policy quality 和 --policy balanced 模式会保留检查点量化和路由器决策,除非传入 --topk 或 --topp;这些显式的有损覆盖会打印警告并继续执行。
自动分层计划根据物理核心数确定 OpenMP 规模,并将工作线程跨核心绑定。当 SMT 兄弟线程争抢有限的内存通道时,内存受限的量化内核可能会急剧退化;显式的 OMP_* 设置始终优先。
coli plan --model /models/glm52_i4 --policy quality
coli run --auto-tier --policy quality "Explain MoE offloading"
# Explicit research-only router reduction:
coli run --policy experimental-fast --topk 4 "Benchmark prompt"
磁盘是不可变的恢复来源,而非正常的解码目标。如果计划将冷专家字节留在磁盘上,速度取决于缓存命中率;输出质量则不受影响。
冷专家读取采用延迟流水线:常驻 RAM/VRAM 专家执行的同时,缺失的专家在有界后台 I/O 池中加载,随后冷结果在层完成前汇入。IO_THREADS=n 在前台工作存在时会覆盖默认的八个加载线程。性能分析会同时报告磁盘服务时间和较小的前台可见等待时间,从而使重叠部分明确可见,而不是被归为无法解释的加速。
--policy balanced 启用无损实时放置(REPIN=64)。在安全的请求边界处,逐层的 LFRU 分数结合了衰减的会话频率与近期访问,并最多替换四个足够冷的固定专家。--policy quality 默认关闭实时替换;REPIN=0 始终禁用它。持久化的 .coli_usage 历史与会话本地的 LFRU 状态保持分离。
对于单 token 的 q4 CPU 专家,gate 和 up 投影共享一次 OpenMP 调度,同时保留相同的逐行 AVX2/NEON 算术。这为每个 RAM 专家减少了一次线程组启动,且无需激活重新量化或更低精度的回退方案。这是迈向持久化原生 CPU 专家池的一块垫脚石,而非其替代品。
专家缓存会根据你的 RAM 自动调整大小(自 2026-07-10 起):引擎现在会提高 LRU 上限以填满你的 --ram 预算,而不再只是降低它。在此修复之前,一台 128 GB 的机器与一台 16 GB 的机器运行着相同的每层 8 专家缓存(issue #12)——如果你在此日期之前对 colibrì 做过基准测试,请重新运行:你的数据当时被上限限制了。
路由器前瞻预取(PILOT=1,实验性):GLM-5.2 的专家路由可以被可测量地提前预测——将第 L+1 层的路由器应用于第 L 层的注意力后状态,可以召回真实 top-8 中的 71.6%(相比之下,“与上一个 token 相同的专家”为 41.3%)。PILOT=1 利用这一点,在当前层进行计算时,从专用 I/O 线程发起下一层专家的预读。在我们的开发机上,磁盘已经约 80% 饱和,因此测得效果为中性;在计算与磁盘较为均衡的机器上(如 issue #12 中的 Ryzen AI 9:43% 磁盘 / 46% matmul),它应当能与真实工作重叠——欢迎提供测量结果。
学习缓存:引擎会记录你的使用实际路由到了哪些专家(.coli_usage 位于模型旁边,每轮更新),并在启动时自动将最热门的专家固定到空闲 RAM 中。colibrì 确实会随着你使用得越多而变得越快。
实时层级自适应(--repin N,需主动启用):在安全的轮次边界,一个衰减的会话热力图会用更热门的流式专家替换冷门的固定专家。替换会将专家从磁盘加载到现有的 RAM 槽位;由 GPU 支持的槽位会立即刷新相同的 VRAM 层级预算。25% 的滞回和四次交换上限可防止层级抖动。持久化的 .coli_usage 仍是长期信号,且不会衰减。
对话重新打开后依然温热(.coli_kv,自 2026-07-10 起):coli chat 在每一轮之后将压缩后的 MLA KV-cache 持久化到磁盘(约 182 KB/token,增量追加,崩溃安全)。关闭聊天,明天再打开——模型依然记得整段对话,并且零重新预填充发生:经校验与不间断会话逐字节一致。:reset 清除它,KVSAVE=0 禁用它。
Web 仪表盘
一条命令即可在同一端口上同时提供 OpenAI 兼容 API 和 Web 控制台,然后在引擎就绪时打开你的浏览器:
cd web && npm install && npm run build # once
./coli web --model <model-dir>
你将获得:
- 聊天并带实时指标:生成时闪烁的 token 计数器,随后是 tok/s、首 token 时间、提示词→补全计数以及队列等待时间;
- 运行时面板:你的硬件(CPU、GPU + VRAM、RAM、核心数)、调度器,以及实时专家层级条——当前 19,456 个专家中有多少位于 VRAM / RAM / 磁盘;
- 大脑:整个模型呈现为一个 76×256 的皮层,每个专家一个单元格。颜色 = 层级,亮度 = 路由热度,每一轮中被路由到的专家会闪白然后衰减——你可以看着模型思考。将鼠标悬停在任意单元格上可查看其层级、热度以及实测主题亲和度(代码、中文、数学、法律等领域的专家位于第 11–22 层)。
仪表盘通过两条极小的协议线路(TIERS、EMAP/HITS)以及普通 JSON 端点与引擎通信——没有任何比引擎本身更重的东西。
有更好的机器?试试看——以下是预期表现
colibrì 是在刻意简陋的硬件上构建的(12 核、25 GB RAM、一块较老的 DRAM-less NVMe,位于 WSL2 VHDX 之后,在这块盘上实测随机读取约 1 GB/s——注意 WSL2 VHDX 本身并不慢:一台社区用户的 5090 机器通过一个 VHDX 实测 O_DIRECT 达到 10.5 GB/s,#101)。这些限制中的每一项都是你的机器可以调高的旋钮。该引擎需要:Linux(或 WSL2)、macOS,或原生 Windows 11(MinGW-w64);带 OpenMP 的 gcc、AVX2、≥16 GB RAM,以及约 370 GB 的 int4 模型存放在本地 NVMe 上(ext4/NTFS——绝不能是网络/9p 挂载)。
如何按顺序测试它:
cd c && ./setup.sh # build + architecture self-test (expects 32/32)
# 1) measure YOUR disk the way the engine uses it (parallel 19 MB random reads):
gcc -O2 -fopenmp iobench.c -o iobench
./iobench /path/to/glm52_i4/out-00069.safetensors 19 64 8 0 # buffered, 8 threads
./iobench /path/to/glm52_i4/out-00069.safetensors 19 64 8 1 # O_DIRECT (bypass cache)
# Caveat (#86): iobench reads a bounded ~1 GB shard, so buffered reads on a big-RAM box
# report the PAGE CACHE, not the disk. Use the O_DIRECT run (arg 1) for a true number, and
# run it on a shard you haven't touched this session (a prior buffered run caches its pages).
# On macOS there is no O_DIRECT — iobench uses F_NOCACHE, which stops *new* caching but can't
# evict pages a prior buffered run already resident-mapped, so a macOS "O_DIRECT" figure right
# after a buffered run still reads cache. Reboot or use a fresh shard for a real cold read.
# 2) chat; watch the per-turn stats line (tok/s, expert hit-rate, RSS):
COLI_MODEL=/path/to/glm52_i4 ./coli chat
# 3) record expert usage, then pin the hottest experts in your spare RAM:
STATS=stats.txt ./coli chat
PIN=stats.txt PIN_GB=20 ./coli chat # scale PIN_GB to your free RAM
# 4) quality benchmarks (MMLU/HellaSwag/ARC):
./coli bench
粗略估算预测(解码受磁盘瓶颈限制:一个冷 token 需要约 11.4 GB 的专家读取;MTP 推测解码在缓存预热后大致将有效成本减半;RAM 将冷读取转化为免费的缓存命中):
| 机器 | 预期 |
|---|---|
| 这台开发机(WSL2 VHDX,约 1 GB/s,25 GB RAM) | ~0.05–0.1 tok/s 冷启动 — 已验证的基线 |
| 原生 Linux,PCIe4 NVMe(随机读写约 3–5 GB/s),32 GB | ~0.5–1 tok/s |
| PCIe5 NVMe 或 2×NVMe RAID0(约 8–12 GB/s),64 GB(PIN 约 40 GB 的热专家) | ~2–4 tok/s |
| 128–256 GB RAM,12 核(热专家已缓存) | ~2–4 tok/s — 受矩阵乘法限制:约 80 GFLOP/token,对比我们的 AVX2 内核约 250 GFLOP/s |
| 相同 RAM + 24–32 核,或 AVX-512/VNNI 内核 | ~5–15 tok/s — 可交互;内核优化工作是倍增器 |
这些是估算值,不是实测数据 — 如果你在真正的硬件上运行 colibrì,请提交 issue 附上你的数据:来自更好机器的真实数据点正是这个项目接下来所需要的。
社区基准测试(实测)
来自真实机器的真实数据,标准构建(setup.sh,gcc 13),贪心解码,--ngen 32,MTP 已启用:
| 机器 | 磁盘(iobench,19 MB × 64,8 线程) | 配置 | 实测 |
|---|---|---|---|
| Intel Core Ultra 7 270K Plus(24 线程)· WSL2 · 24 GB RAM · NVMe VHDX(#2) | 1.96 GB/s 缓冲 · 2.74 GB/s O_DIRECT | 默认 | 0.07 tok/s · 专家命中率 3–4% · RSS 14.1 GB |
| 〃 | 〃 | --topp 0.7 | 0.11 tok/s · 专家命中率 11% · RSS 14.7 GB |
| Apple M5 Max(18 核)· macOS · 128 GB 统一内存 · 内置 SSD(#4,#5) | 冷启动约 4 GB/s(14.2 GB/s 的读数是受缓存影响——见备注) | 默认,MTP 关闭 | 1.06 tok/s · 专家命中率 23% · RSS 21.8 GB |
| Apple M5 Max · macOS · 128 GB 统一内存 · 2 TB SSD · Metal 后端(#72、#87) | (macOS O_DIRECT 数据不可靠——见备注) | Metal 开启 · --ram 96 · 39.7 GB 热固定 · MTP 关闭 | 1.83 tok/s · 专家命中率 66% · 运行过程中从 1.11 预热提升至 1.83 |
同上 · 46.9 GB 固定(2.94M 选择历史)· --ram 110,1024-token 运行(#103) | 同上 | Metal 开启(专家 + 注意力)· MTP 关闭 | 2.06 tok/s · 命中率 72.5% · 输出连贯 · 目前最快的数据点(仍在 rebase 前的 Metal 分支上) |
| Mac Mini M4 Pro · macOS · 48 GB 统一内存 · Metal 后端(#107) | 6.59 GB/s F_NOCACHE(全新分片) | Metal 开启 · --ram 38 | 0.30 tok/s(对比纯 CPU 的 0.18)——入门级 Apple Silicon 用三分之一的 RAM 就击败了 32 核 9950X 那一行 |
| Epyc 9654 ES · Linux · 4x16GB DDR5-4800-rdimm · Samsung PCIe Gen3 x4 NVME SSD | — | MTP=1 DIRECT=1 | 0.31 tok/s · 专家命中率 35% · RSS 21.52 GB |
| Ryzen AI 9 HX 370(Framework 13)· Arch Linux · 128 GB · WD SN850X,BTRFS zstd(#12) | — | int8 MTP head · --cap 32 · 46.7 GB 自动学习 PIN | 0.37 tok/s · 专家命中率 66% · MTP 接受率 52%(2.59 tok/fw)· RSS 105 GB |
| Ryzen 9 9950X(32 线程)· Linux · 123 GB · Crucial P3 QLC Gen3(#31) | 1.51 GB/s 缓冲 | 默认配置,冷启动运行 2 次 | 0.10 tok/s · 命中率 53% · 磁盘占用 66% |
| 〃 同一台机器,模型移至 Samsung 9100 PRO PCIe 5.0(#31) | 8.81 GB/s O_DIRECT | 〃(保留使用历史) | 0.28 tok/s · 命中率 57% · 性能剖析翻转:32% 磁盘 / 57% matmul |
| Ryzen AI Max+ 395(Framework Desktop)· Ubuntu · 128 GB LPDDR5x · Intel Optane 905p PCIe 3.0(#39) | 3.27 GB/s 缓冲 | int8 MTP head · 全新历史(纯 LRU,自动提升上限 65) | 0.16 tok/s · 命中率 57% · 性能剖析 49% 磁盘 / 47% matmul |
| 〃 五次运行后 —— 学习到固定 47.6 GB(#39) | 〃 | --temp 0.7 --topp 0.7 | 0.40 tok/s · 命中率 71% · 最快的非 Apple 数据点 |
| Ryzen 7 9800X3D(16T)· WSL2 · 70 GB RAM · Samsung 9100 PRO PCIe 5.0 · RTX 5090(#101) | 10.51 GB/s O_DIRECT | MTP 关闭 · 学习到的 pin 24 GB · 命中率 54% · OMP 热团队开启 | 0.41 tok/s · 受磁盘瓶颈限制(磁盘 36.5 s 对比 matmul 24.0 s)· CUDA 专家层 ≈ 0%(AVX-512 CPU 与 5090 相当)· --topp 0.7 → 0.52 tok/s |
| EPYC 7443(24C/48T,Zen3 AVX2)· Linux · 430 GB RAM · 通过 TrueNAS VM 的 NVMe RAID-Z1(#104) | ~1 GB/s(VM 开销) | 77.5 GB pin · 上限自动提升至 194/层 · MTP 关闭 | 1.00 tok/s · 命中率 98% · 磁盘瓶颈消除 → 受 RAM 带宽 + matmul 瓶颈限制(Zen3 上没有 AVX-512/VNNI) |
| Intel i5-12600K(10C/16T,AVX2)· 原生 Windows 11,无 WSL · 32 GB · MinGW GCC 16.1(#113) | 带缓冲(MinGW 上无 O_DIRECT) | int8 MTP 头 · 冷启动,小内存(上限约 2/层) | 0.08 tok/s · 命中率 3.7% · MTP 接受率 57% —— 首个原生 Windows 数据点,移植已验证 |
| Ryzen 9 9950X3D2(16 核/32 线程,avx512-vnni)· 原生 Linux · 121 GB · Samsung 9100 PRO PCIe Gen5 · RTX 5090(28 GB 专家层,1475 固定)(#120) | 11.48 GB/s O_DIRECT | MTP=0 DIRECT=1 PIPE_WORKERS=16 PREFETCH=1 | 1.23 tok/s · 关闭 MTP 在磁盘受限场景下胜出 · 目前最快的 x86 数据点 |
| Ryzen AI Max+ 395(Strix Halo,16 核/32 线程 Zen5,avx512-vnni)· Arch Linux · 128 GB 统一 LPDDR5x · SK hynix P41 PCIe 4.0(#124) | —— | DIRECT=1 PIPE=1 --topp 0.7 · 自动固定 | 冷启动 0.06 → 持续 1.10 tok/s · 首个 Strix Halo / gfx1151 数据点(统一内存:无独立 VRAM 层级) |
| Intel Core Ultra 9 185H(16 核/22 线程,avx-vnni)· 原生 Windows 11,无 WSL · 32 GB · Crucial P3 QLC NTFS · RTX 5070 Ti(未使用)(#128) | —— | int8 MTP head · 配合 #131(管道 + RAM 修复),热缓存,无 GPU | 0.03 冷启动 → 0.5 tok/s 热启动(约 7 条提示词预热)· 一旦可移植性障碍修复,即可在原生 Windows 上预热缓存——在 #131 之前,原版 main 卡在 \r\n READY 哨兵上 |
| Dell Pro Max GB10(DGX Spark:Grace 10×X925 + 10×A725,aarch64 i8mm/sve2)· Linux · 121 GB 统一 LPDDR5x · Dell OEM 4 TB NVMe · GB10 sm_121(#136) | 5.58 GB/s O_DIRECT(#76 中的 NVIDIA-OEM 机型为 10.74——同一平台,不同 SSD) | int8 MTP head · 热缓存 | 0.21 冷启动 → 0.50 tok/s 热启动 · 命中率 83% · MTP 73%(3.20 tok/fw)· 受限于矩阵乘法(矩阵乘法 130 秒 vs 磁盘 58 秒)——统一内存,CUDA 放置层级中性;这里的杠杆是 i8mm 计算内核,而非放置策略 |
要点:在 24 GB 内存下,引擎会自动把专家缓存上限压到每层 2 个槽位,因此即使磁盘比开发机快 2–2.7×,解码依然处于冷态——在小内存机器上,约束瓶颈是内存上限,而不是磁盘,正如上表所预测;仅靠 --topp 0.7 就带来了干净的 1.6× 端到端加速。M5 Max 的数据点正好落在表格第二行:在笔记本 SSD 上跑 744B 模型约 1 tok/s——而它 14 GB/s 的磁盘把瓶颈重新推回到内存预算和 kernel 上。Framework 13 那几行则是在同一台机器上端到端验证了缓存这一论点:仅仅把内存还给缓存,就从 0.29 → 0.37 tok/s(命中率 28% → 66%,推测解码终于在 52% 接受率下开始生效)——int8 MTP head + 更大的上限 + 学习到的 pin。上限这部分现在已自动化(上限自动提升,2026-07-10)。9950X 那一对是目前最干净的瓶颈实验——同一台机器、同一份历史记录,只换了磁盘:×5.8 的磁盘带宽换来了 ×2.9 的 token 数,而 profile 从 66% 磁盘翻转为 57% matmul。但这个交叉点取决于 CPU kernel:9800X3D 那一行(#101)显示,在开启 OMP 热团队调优后,AVX-512 CPU matmul 已经足够快,以至于即便是 10 GB/s 的 NVMe 也仍然受磁盘限制——而在那里,CUDA 专家层带来的收益约为 0%,因为 CPU 在专家 matmul 上已经追平了 5090。GPU 层只有在 CPU 是薄弱环节时才配得上它的 VRAM,而不是默认如此。(来自 #101 的诚实更正:该报告早先的版本是在 OMP 调优关闭的情况下运行的,这制造出了一个虚假的 matmul 瓶颈交叉点和 CUDA 虚假的 +14%——两者在干净重跑后都不复存在。)
质量基准测试——寻求帮助
首次测量结果出来了(#108,感谢 dnnspaul):int4 容器在 hellaswag/arc/mmlu 上取得了 62.5% 的平均 acc_norm(0-shot 对数似然,n=40)——低于全精度 GLM-5.2 公布的 85–95%,但这一差距目前还不能归因于量化。有两个混淆因素挡在路上:(1) 0-shot 对数似然 MC 评分对 GLM-5.2 这样的推理模型服务得极差(它根本没机会思考),所以即便在 fp16 下也会预期出现较大差距;(2) n=40 意味着 ±14pp。决定性实验是在同一套测试框架下做 OLMoE 的 fp16 对 int4 A/B 对比(模型足够小,两种精度都能跑)——那个差值就是在评分协议被抵消掉之后的量化成本。在它跑出来之前,62.5% 只是一个数据点,而非定论。
代码在这里,已经就绪;一条命令即可端到端运行(首次使用时会自动下载数据集):
cd c
pip install tokenizers datasets # in addition to the convert deps above
./coli bench # hellaswag, arc_challenge, mmlu — 40 questions each
./coli bench hellaswag --limit 200 # one task, more questions
./coli bench mmlu arc_challenge --ram 100 # pick tasks, set a RAM budget
它会打印每个任务的准确率(对数似然评分,EleutherAI harness 风格)。如果你能跑 OLMoE 的 fp16 对 int4 A/B 对比(或大 n 的 GLM 运行),请带着数字开一个 issue——正是这项测量能把 62.5% 变成要么“int4 没问题,是评分假象”,要么“量化就是天花板,分组缩放才是优先事项”。
支持本项目
colibrì 是一个单人项目,完全在一台 12 核、25 GB 内存的笔记本上编写和测试——上面这些数字就是我在家里所能测到的上限。如果这个项目对你来说有用或有趣,并且你愿意支持它的开发(更好的测试硬件会直接转化为对所有人更快的引擎:真实的 NVMe 扩展数据、更大的固定缓存、在真实基准上的 int2/int3 质量扫描),你可以:
- ⭐ 给仓库点 star 并分享它;
- 🐛 提交 issue,附上你硬件上的基准测试数字;
- 💬 如果你想赞助开发或捐赠硬件,可以通过 GitHub issue 联系我。
每一份贡献,从一个数据点到一块硬盘,都在推高这个上限。
仓库结构
Makefile root build/check entry point
c/
├── glm.c single-file GLM engine
├── st.h, tok.h, json.h runtime headers
├── backend_cuda.* optional CUDA tier
├── Makefile build and local checks
├── coli user-facing CLI
├── openai_server.py OpenAI-compatible HTTP gateway
├── setup.sh one-command local setup
├── tools/ offline conversion, fixtures and benchmarks
├── scripts/ long-running conversion helpers
└── tests/ dependency-free C and Python tests
web/ browser UI (pure OpenAI-API client, community-maintained)
运行时路径有意保持扁平且易读:glm.c 加上它的小型头文件。辅助性的 Python 和 shell 工具单独分组,且从不是引擎的运行时依赖。
从仓库根目录开始,make、make check 和 make clean 都会委托给引擎的 Makefile。从 c/ 运行的现有命令继续照常工作,无需改动。
为什么叫 "colibrì"
蜂鸟体重仅几克,能原地悬停,一天造访上千朵花。而这个引擎让一个 7440 亿参数的庞然大物靠蜂鸟般的口粮存活:25 GB 内存、十二个 CPU 核心,以及大量的磁盘耐心。
许可证
Apache 2.0。GLM-5.2 的权重由 Z.ai 以 MIT 许可证发布。
来源:Hacker News 热门(buzzing.cc 中文翻译) · github.com