第 1 章 · 02 纯 C 零依赖与一个 .c 一个模型族


文档摘要

第 1 章 · 02 纯 C 零依赖与一个 .c 一个模型族 本节摘要:本节讲清 Colibrì 的两条架构红线——纯 C 零引擎依赖(无 BLAS、无 Python 运行时、无 GPU 必须),与一个 一个模型族( GLM-5.2 / / / / )。介于两者之间的,是一组共享头文件( / / / )——所有模型族都 include 它们,机制集中在头里,一改全改。这条规则不是装饰,反复出现的缺陷就是"某机制只落在一个引擎、没传到兄弟引擎"。顶层 只用一行委托给 , / / 统一入口。读完本节,你理解了 Colibrì 仓库的整体形状。 内容来源:原项目源码 ("The idea" 段)、顶层 、 目录文件清单与行数统计。

第 1 章 · 02 纯 C 零依赖与一个 .c 一个模型族

本节摘要:本节讲清 Colibrì 的两条架构红线——纯 C 零引擎依赖(无 BLAS、无 Python 运行时、无 GPU 必须),与一个 .c 一个模型族(colibri.c GLM-5.2 / deepseek_v4.c / inkling.c / kimi_k3.c / olmoe.c)。介于两者之间的,是一组共享头文件(st.h/quant.h/tok.h/expert_store.h)——所有模型族都 include 它们,机制集中在头里,一改全改。这条规则不是装饰,反复出现的缺陷就是"某机制只落在一个引擎、没传到兄弟引擎"。顶层 Makefile 只用一行委托给 c/Makefile,make/make check/make clean 统一入口。读完本节,你理解了 Colibrì 仓库的整体形状。

内容来源:原项目源码 README.md("The idea" 段)、顶层 Makefilec/ 目录文件清单与行数统计。

⚠️ 注意:"零引擎依赖"指的是运行时不需要 BLAS/CUDA/Metal 这类引擎库——它们是可选后端(CUDA=1/METAL=1/VULKAN=1 才编译进来),不是必须。CPU-only 路径只用标准库和 OpenMP,能在任何带 C 编译器的机器上 make 出来。

学习目标

阅读完本节,你应当能够:

  1. 解释为什么 Colibrì 选纯 C 而不是 C++/Rust/Python。
  2. 说出"零引擎依赖"的精确含义(CPU-only 路径只要标准库 + OpenMP)。
  3. 复述五个模型族对应的五个 .c 文件名与各自行数。
  4. 解释共享头文件设计为什么是"一改全改",并列出四类共享机制。
  5. 理解"一个机制只落在一个引擎、没传到兄弟"为什么是反复出现的缺陷。
  6. 读懂顶层 Makefile 一行委托的写法和 repo layout。

一、纯 C 零引擎依赖

README.md "The idea" 段最后一句给 Colibrì 的极简画像:

The engine is a single C file (c/glm.c) plus small headers. No BLAS, no Python at runtime, no GPU required.

注意三个"no":

  • No BLAS:不依赖 OpenBLAS/MKL/ Accelerate 这类线性代数库。Colibrì 自己在 quant.h 里写了多架构 SIMD 的 matmul 内核(AVX2/AVX-512/NEON/VSX,第 2 章详讲)。
  • No Python at runtime:训练侧、打包侧有 Python(colibri/cli.pyrepack_*.py),但推理时不需要 Python 运行时coli chat 启动的是纯 C 编译出来的二进制。
  • No GPU required:GPU 后端(CUDA/Metal/Vulkan)是可选编译项(CUDA=1/METAL=1/VULKAN=1),不编就是 CPU-only,照样能跑。

为什么选纯 C?Colibrì 的隐含理由可以归纳成三点:

  1. 可移植性的极致:只要目标机有 C 编译器(甚至 mingw 交叉编译都行),make 就出二进制。c/Makefile 头部用 gcc -dumpmachine 探测目标三元组,自动识别 mingw/cygwin/darwin/linux/powerpc,这是 C 的天然优势。
  2. 零运行时开销:没有 Python 解释器启动、没有 GC、没有 vtable 抽象层(虚函数表除外,见第 3 章 ColiExpertStoreOps),贴近硬件。
  3. 可读、可改、可贡献:README.md 说 "the engine is deliberately small enough that the next useful optimization can come from anyone willing to measure it"——引擎刻意保持小到任何人愿意测量就能贡献优化。纯 C 是这套"开放研究平台"哲学的载体。

💡 深潜要点:不要把"纯 C"误解为"落后"。Colibrì 选 C 是有意识的设计选择,目的是把"软件/硬件边界"上的每一处优化(模型格式、内存层级、I/O、放置、调度、kernel、推测、CPU/GPU 重叠)都暴露给研究者和贡献者。C++的抽象层、Python 的运行时,都会把这条边界糊掉。

补充一点:C 路径上唯一的"重型依赖"是 OpenMP——quant.h:13-15#ifdef _OPENMP 条件引入 omp.h,matmul 内核用 #pragma omp parallel for 多线程。OpenMP 是 C/C/Fortran 的标准编译制导(几乎所有主流编译器 gcc/clang/msvc 都内置),不算"引擎依赖"。即便没有它,代码也能编译(退化成单线程),只是慢。c/omp_tune.h 还专门做 OpenMP 调优(线程数、调度策略),这是 Colibrì 把"软件/硬件边界"暴露到极致的又一例——连线程数都让用户量着调。

二、一个 .c 一个模型族

第二红线:一个 .c 文件对应一个模型族。仓库 c/ 目录下的五个引擎源码及行数(wc -l 实测):

模型族 引擎源码 行数
GLM-5.2(744B) c/colibri.c 9514
DeepSeek V4 Flash(284B) c/deepseek_v4.c 10993
Inkling(975B) c/inkling.c 2250
Kimi K3(2.8T) c/kimi_k3.c 1938
OLMoE(7B) c/olmoe.c 1211

每个 .c完整的、自包含的推理引擎——它知道这个模型族的架构(层数、隐藏维度、MoE 拓扑、attention 变体)、知道怎么路由、怎么算 attention、怎么解码。从行数能看出规模差异:olmoe.c 只有 1211 行(7B 小模型,最简单),deepseek_v4.c 有 10993 行(284B,但 attention 变体 MLA 复杂、还含 native FP8 读取路径)。

这种"一模型一文件"的设计有几层好处:

  • 架构隔离:GLM-5.2 的 DSA sparse attention 不会污染 DeepSeek V4 的 MLA。每个模型族的怪癖都封装在自己的 .c 里。
  • 可对照阅读:想比较两个 MoE 架构的路由实现?并排打开 colibri.cdeepseek_v4.c 直接读。
  • 编译选择:c/Makefile 让你选择编哪个目标(make glm/make deepseek-v4),不用的模型不编进来。

但这条规则有个内在张力:很多机制是所有模型族都需要的(safetensors 解析、量化解码、tokenizer、专家缓存)。如果每个 .c 都自己写一份,代码会爆炸式重复,且某个 bug 修了一处忘了同步另一处——这就是下一节"共享头文件"要解决的问题。

三、共享头文件:一改全改

介于"五个独立 .c"和"一份共享代码"之间的,是一组所有引擎都 include 的头文件。它们承载了"所有模型族都需要的通用机制":

头文件 行数 作用
c/st.h 852 safetensors 索引与范围读取(第 2 章)
c/quant.h 1569 量化容器解码器 + 多架构 SIMD matmul(第 2 章)
c/tok.h 581 tokenizer(O200K / BPE)
c/expert_store.h 99 专家流式缓存抽象 + lease 契约(第 3 章)
c/tensor.h 47 ColiTensorView 容器格式枚举

设计规则可以一句话总结:

一个引擎拥有自己的架构;两个引擎都需要的机制——放头文件,所有引擎 include,一改全改。

为什么是头文件而不是独立的 .c?因为 Colibrì 追求"单文件可编译"——每个引擎 .c 直接 #include "st.h"/#include "quant.h"/#include "expert_store.h",所有函数都是 static inline(header-only),编译时整个引擎就是一个翻译单元,没有链接步骤,没有动态库依赖。这种风格在 quant.h:1-3 的注释里写得很直白:

1 /* quant.h — quantized matmul kernels (header-only, all functions static). 2 * Multi-architecture SIMD: AVX2 / AVX-512 / AVX-VNNI / ARM NEON / NEON-SDOT / 3 * NEON-i8mm / POWER VSX. Pure compute — no Model or QT dependency. */

三个关键修饰:header-only(纯头文件)、all functions static(全 static,允许每个 .c 各自包含不冲突)、pure compute — no Model or QT dependency(纯计算,不依赖任何模型结构体)。

⚠️ 注意:这条共享头文件规则不是装饰,而是 Colibrì 维护者反复强调的纪律。源码注释里到处可见"反复出现的缺陷就是某机制只落在一个引擎、没传到兄弟引擎"的反思——例如 st.h 早期版本只支持 BF16/F16/F32 三种 dtype,加 F8_E4M3 时如果只改 colibri.c 不改 deepseek_v4.c(它要读 native FP8 权重),就会在 DeepSeek V4 的某个 I64 张量处直接 exit(1)。所以新机制必须先落到头里,再让所有引擎同步受益。

四、顶层 Makefile 与 repo layout

仓库根的 Makefile 只有一行有效内容,极其朴素:

1 .PHONY: all glm deepseek-v4 portable test check cuda-test clean install uninstall 2 3 all glm deepseek-v4 portable test check cuda-test clean install uninstall: 4 $(MAKE) -C c $@

这是一个透传 Makefile:无论你 make/make check/make clean/make glm/make deepseek-v4,它都委托给 c/Makefile,把目标名 $@ 原样传过去。所有真正的编译逻辑都在 c/Makefile(里面用 gcc -dumpmachine 探测平台、按目标选 CC、按变量 CUDA=1/METAL=1/VULKAN=1 决定要不要编 GPU 后端)。

整个 repo 的 layout:

colibri-main/ ├── c/ # 纯 C 引擎核心(本教程的精读对象) │ ├── colibri.c # GLM-5.2(9514 行) │ ├── deepseek_v4.c # DeepSeek V4(10993 行) │ ├── inkling.c # Inkling(2250 行) │ ├── kimi_k3.c # Kimi K3(1938 行) │ ├── olmoe.c # OLMoE(1211 行) │ ├── st.h quant.h tok.h expert_store.h tensor.h ... # 共享头 │ ├── backend_cuda.h backend_metal.h backend_vulkan.c # GPU 后端 │ ├── Makefile # 真正的编译逻辑 │ └── tools/ # 打包/重打包 Python 脚本 ├── colibri/ # Python CLI(cli.py)、resource_plan、openai_server ├── web/ # 浏览器 UI(纯 OpenAI-API 客户端) ├── desktop/ # Tauri v2 桌面壳 ├── docker/ # 容器 ├── docs/ # 文档(FORMATS.md/benchmarks.md/media/) └── Makefile # 顶层透传 Makefile

注意 c/ 目录是本教程前 8 章的全部精读对象;colibri/web/desktop/docker/ 是第 9 章的 CLI/服务/Web 全栈。docs/ 里的 FORMATS.md 是第 2 章 02 节的主角(格式注册表治理)。

💡 深潜要点:顶层 Makefile 的"透传一行"是 Colibrì 工程文化的缩影——核心机制都在 c/,Python/Web/Desktop 都是壳。后续章节你会反复回到 c/ 目录,把它当成整本书的舞台。

本节要点回顾

  1. 纯 C 零引擎依赖:无 BLAS、无 Python 运行时、无 GPU 必须;CPU-only 路径只要标准库 + OpenMP。
  2. .c 一模型族:colibri.c(9514)/deepseek_v4.c(10993)/inkling.c(2250)/kimi_k3.c(1938)/olmoe.c(1211)。
  3. 共享头文件:st.h/quant.h/tok.h/expert_store.h/tensor.h,header-only、all static、pure compute,一改全改。
  4. 共享纪律:反复出现的缺陷就是"某机制只落在一个引擎、没传到兄弟",所以新机制先落头文件。
  5. 顶层 Makefile 透传:make/make check/make clean 委托给 c/Makefile,所有编译逻辑在 c/

下一节,我们走完 per-token 的五步路径(route→union→place→overlap→learn),并理解 Colibrì 的"诚实研究"风格——每个优化都是可证伪假设,必须受控端到端 A/B 验证。


作者与出处
原作者: 灏天文库
整理: 灏天文库整理
本站整理收录,版权归原作者/开源协议所有;欢迎通过原文链接访问源仓库。
发布者: 作者: 灏天文库 转发
评论区 (0)
U