第 9 章 · 01 coli CLI 与 resourceplan.py 本节摘要:本节深潜 Colibrì 的用户接入层入口—— CLI。它是一个纯 Python 脚本( ),把所有用户操作收敛成一组子命令: (交互流式)/ (OpenAI 兼容服务)/ (Web UI)/ (RAM/VRAM 规划)/ (环境诊断)/ / / / / / / / 。 是 pip 安装后的入口包装, 是 / 背后的规划器——检测 RAM/VRAM 预算和后端,生成磁盘/RAM/VRAM 三级放置配置。本节贴 与 、 的关键源码。 内容来源:原项目源码 、 、 ⚠️ 注意: 是 Python 脚本不是编译产物,直接 就能跑。 后它被放到 ,引擎和支持模块( / / )放到 —— 内部会去找它们。
本节摘要:本节深潜 Colibrì 的用户接入层入口——
coliCLI。它是一个纯 Python 脚本(c/coli),把所有用户操作收敛成一组子命令:chat(交互流式)/serve(OpenAI 兼容服务)/web(Web UI)/plan(RAM/VRAM 规划)/doctor(环境诊断)/info/mirror/bench/convert/build/run/tune/stop。colibri/cli.py是 pip 安装后的入口包装,resource_plan.py是plan/doctor背后的规划器——检测 RAM/VRAM 预算和后端,生成磁盘/RAM/VRAM 三级放置配置。本节贴coli与cli.py、resource_plan.py的关键源码。
内容来源:原项目源码
c/coli、colibri/cli.py、c/resource_plan.py
⚠️ 注意:
coli是 Python 脚本不是编译产物,直接./coli chat就能跑。make install后它被放到$(PREFIX)/bin/coli,引擎和支持模块(resource_plan.py/doctor.py/openai_server.py)放到$(PREFIX)/libexec/colibri——coli内部会去找它们。
coli 的全部子命令并说清各自用途。colibri/cli.py 为什么是"薄包装"——它把所有逻辑委托给 c/coli。resource_plan.py 如何从模型 safetensors 头 + 硬件探测 + 后端检测生成三级放置 plan。coli doctor 检查哪些项(依赖、模型、磁盘、版本)。COLI_ENGINE/COLI_MODEL 环境变量的作用。coli 子命令一览coli 用 argparse 注册子命令。源码 1337-1406 行把全部子命令注册出来:
1337 sub=ap.add_subparsers(dest="cmd") 1338 sub.add_parser("build", parents=[common]); sub.add_parser("info", parents=[common]) 1339 pp=sub.add_parser("plan",parents=[common]) 1341 pm=sub.add_parser("mirror", parents=[common], ...) 1349 pd=sub.add_parser("doctor",parents=[common]) 1353 pt=sub.add_parser("tune", parents=[common], ...) 1363 pr=sub.add_parser("run", parents=[common]); pr.add_argument("prompt", nargs="*") 1364 pc=sub.add_parser("chat", parents=[common]) 1372 ps=sub.add_parser("serve", parents=[common]) 1383 pst=sub.add_parser("stop", parents=[common], help="shut down a running coli serve ...") 1385 pw=sub.add_parser("web", parents=[common], help="serve + open the dashboard ...") 1398 pb=sub.add_parser("bench", parents=[common]); pb.add_argument("tasks", nargs="*") 1406 pc=sub.add_parser("convert", parents=[common]); pc.add_argument("--repo",default="zai-org/GLM-5.2-FP8")
coli 顶部 docstring 把核心子命令的用途直接列出:
coli chat interactive chat (loads the model once) coli serve OpenAI-compatible HTTP API (persistent engine) coli run "prompt" one-shot generation coli info model, RAM, disk, and configuration status coli plan Disk / RAM / VRAM resource plan coli mirror Plan, stage, or verify a learned partial mirror coli doctor installation and execution-plan diagnostics coli bench [task...] quality benchmarks (MMLU/HellaSwag/...) coli convert convert GLM-5.2-FP8 to int4, one shard at a time coli build build the engine
最常用的五个(本教程主线):
coli chat:交互式流式聊天,引擎只加载一次,后续 turn 复用同一进程(配合第 7 章 02 节的 KV 前缀复用);coli serve:启动 OpenAI 兼容 HTTP 服务(openai_server.py),引擎持久驻留,第 9 章 02 节展开;coli web:serve + 自动开浏览器加载 dashboard(第 9 章 03 节);coli plan:不跑模型,只探测硬件 + 解析模型头,生成三级放置 plan;coli doctor:环境诊断,检查依赖、模型完整性、磁盘空间、版本一致性。colibri/cli.py:pip 安装的薄入口colibri/cli.py 全文 27 行,核心是把控制权交给 c/coli:
"""Entry point for `coli` when installed via pip. Delegates to the original c/coli script which handles all subcommands. This wrapper exists so `pip install colibri-engine` creates a `coli` console script that works without the user having to add c/ to PATH manually. """ import os, sys, runpy def main(): here = os.path.dirname(os.path.abspath(__file__)) engine_dir = os.path.join(os.path.dirname(here), "c") coli_script = os.path.join(engine_dir, "coli") if not os.path.exists(coli_script): sys.exit("colibri engine directory not found.\n" "Install from source: git clone + pip install -e .") sys.path.insert(0, engine_dir) sys.argv[0] = coli_script runpy.run_path(coli_script, run_name="__main__")
这是 PyPI 包 colibri-engine 的 console_script 入口——pip install colibri-engine 后,coli 命令就是这层壳。它做的事只有三件:
c/coli 脚本(在已安装布局里找 c/ 目录);c/ 加入 sys.path(让 import resource_plan 等能解析);runpy.run_path 以 __main__ 身份执行 c/coli,完整转发命令行参数。💡 深潜要点:为什么不一上来就把所有逻辑写在 Python 包里?因为
coli还要启动 C 编译出来的引擎二进制(colibri/glm)。Python 部分只是"参数解析 + 引擎 subprocess 调度 + 工具脚本粘合",真正的推理逻辑全在 C 侧。这种"薄 Python 壳 + 厚 C 内核"是 Colibrì 一贯的工程取向。
resource_plan.py:三级放置规划器resource_plan.py 是 coli plan 和 coli doctor 背后的核心。它做四件事:
analyze_model):读所有 *.safetensors 的头,把张量按"稠密部分"和"专家组"分类,统计各自字节;memory_available / discover_gpus / physical_cpu_count):查可用 RAM、NVIDIA/AMD GPU 及显存、物理核数、NUMA socket 数;build_plan):把模型 + 硬件 + 上下文长度喂给 _auto_tune,输出三级放置配置(dense 常驻多少、专家 cache 多大、VRAM 驻留多少);environment_for_plan / format_plan):把 plan 翻译成 COLI_* 环境变量集合 + 人类可读的表格。analyze_model 的核心是分类稠密张量和专家张量:
18 def _tensor_sizes(path): 19 file_size = path.stat().st_size 20 with path.open("rb") as stream: 21 raw = stream.read(8) ... 25 header = json.loads(stream.read(length)) 26 for name, meta in header.items(): ... 30 yield name, end - start 37 def analyze_model(model): ... 43 EXPERT_RE = re.compile(r"model\.layers\.(\d+)\.mlp\.experts\.(\d+)\.") 44 dense_bytes = 0 45 expert_groups = {} 46 for shard in shards: 47 for name, size in _tensor_sizes(shard):
EXPERT_RE 正则把 model.layers.N.mlp.experts.K.* 形式的张量识别为专家权重,按 layer 分组;其他归稠密部分。这正是第 1 章/第 4 章的"稠密常驻 RAM + 专家放磁盘"在 Python 规划层的落地。
build_plan(523 行起)综合 RAM/VRAM 预算、上下文长度、GPU 列表、_auto_tune 的瓶颈分类(CPU-bound/disk-bound/bandwidth-bound),给出 COLI_RAM_GB、CUDA_EXPERT_GB、PIN_GB、COLI_MODEL_MIRROR 等配置——这些就是第 4-8 章所有 C 侧开关的"上层来源"。
coli doctor:环境诊断cmd_doctor(740 行起)调用 doctor.py,逐项检查:
config.json、safetensors 完整性、专家张量计数与 config.json 声明是否一致;version.py 是否一致,与 PyPI 已发布版本是否匹配;resource_plan.build_plan,看输出是否合理(比如 RAM 是否塞得下稠密部分)。每一项都给出明确的修复建议,而不是"失败 = 报错退出"。这呼应 coli 顶部第 65-67 行的"no invented default"哲学:永远不发明一个数,失败要让用户知道下一步该做什么。
COLI_ENGINE/COLI_MODELcoli 内部需要定位两样东西:引擎二进制和支持模块。源码用三层 fallback 实现:
_EXE = ".exe" if sys.platform == "win32" else "" _LIBEXEC = os.path.join(os.path.dirname(HERE), "libexec", "colibri") _here_colibri = os.path.join(HERE, "colibri" + _EXE) _here_glm = os.path.join(HERE, "glm" + _EXE) if os.environ.get("COLI_ENGINE"): GLM = os.environ["COLI_ENGINE"] TOOLS = os.path.join(os.path.dirname(GLM), "tools") elif os.path.exists(_here_colibri): GLM = _here_colibri # run-in-place: c/colibri elif os.path.exists(_here_glm): GLM = _here_glm # 老布局回退: c/glm else: GLM = os.path.join(_LIBEXEC, "colibri" + _EXE) # installed: libexec/colibri/colibri ...
环境变量优先级:
COLI_ENGINE:显式指定引擎二进制路径,覆盖一切自动检测(自定义打包布局用);COLI_MODEL:模型目录,所有子命令的默认值。coli 顶部明确写"no invented default"——不设就没默认值,每个子命令用各自的方式报"pass --model , or set COLI_MODEL="。setup.sh 与安装流程c/setup.sh 是构建脚本,coli build 内部调用它。典型流程:
CUDA=1/METAL=1/VULKAN=1)决定编译哪些后端;c/colibri(主引擎二进制);make install 把 coli 放到 $(PREFIX)/bin/,把 colibri + 支持模块放到 $(PREFIX)/libexec/colibri/。coli 自身可以独立于引擎二进制存在——doctor/plan 这些不依赖推理引擎,纯 Python 就能跑,这也是为什么"先 coli doctor 再 coli build"是排查问题的标准流程。
coli 是 Python CLI,子命令包括 chat/serve/web/plan/doctor/info/mirror/bench/convert/build/run/tune/stop,核心五个是 chat/serve/web/plan/doctor。colibri/cli.py 是 pip 安装后的 27 行薄入口,用 runpy.run_path 把控制权交给 c/coli,让 pip install colibri-engine 自动创建 coli console script。resource_plan.py 是 plan/doctor 的核心:analyze_model 分类稠密/专家张量,discover_gpus/physical_cpu_count 探测硬件,build_plan 给出 COLI_* 环境变量配置——这就是第 4-8 章 C 侧开关的上层来源。coli doctor 检查依赖/模型/磁盘/版本/plan 健康性,每项给修复建议,不"发明默认值"(#724 教训)。COLI_ENGINE/COLI_MODEL 是两个核心环境变量;run-in-place 找 c/colibri,installed 找 libexec/colibri/colibri;setup.sh 是构建脚本,coli build 调用它。下一节我们看
coli serve启动的openai_server.py——OpenAI 兼容 HTTP 网关,以及它如何把 continuous batching、grammar 约束、speculative decoding、kv_prefix 串联起来。