不安装 Python、PyTorch、Conda、Docker,也不启动常驻模型服务:一个 Rust 对象、一份 GGUF 权重,就能把原生多模态推理放进自己的进程。
我们在一台 24 GB 内存、10 核 Apple M5 的 MacBook Air 上跑通了这条路径。当前 release 版 zllm-metal 只有 8.1 MB;配合 Gemma 4 E4B 的 Q4_K_M 主模型和视觉投影,它可以直接通过 Metal 完成多轮对话与图像理解。
先说清"零依赖"的边界:这里指的是交付和运行时不依赖第三方推理框架。最终用户不需要 Python、PyTorch、Conda、Docker 或单独管理的 C++ runtime;模型权重仍然必需,macOS 自带的 Metal 与系统框架也仍然存在。
为什么做成库,而不是再起一个服务?
zLLM 不是另一个本地 HTTP 服务的包装。zllm::embedded::Engine 直接在调用方进程内持有模型、Metal backend、KV Cache 和生成状态:
arduino
Rust 应用
└─ Engine::from_config(装载一次)
├─ GGUF 权重与 chat template
├─ Metal backend / kernels
└─ terminal KV Cache
↓
Engine::generate(重复调用)
├─ Chat JSON → template → tokenize
├─ 可选 image_url → mmproj → 视觉 embedding
├─ prefill / append prefill / decode
└─ 每个 token 通过 Rust 回调返回
应用自己拥有线程、取消、缓存和生命周期,不需要跨进程调用,也不需要管理 Metal command buffer。
嵌入现有 Rust 程序
引擎只加载一次,之后可以反复调用 generate:
rust
use std::io::{self, Write};
use serde_json::json;
use zllm::embedded::Engine;
fn main() -> Result<(), String> {
let mut engine = Engine::from_config("gemma4-metal.yaml")?;
let cancellation = engine.cancellation();
let result = engine.generate(
&json!({
"model": "gemma4",
"messages": [{
"role": "user",
"content": "用一句话解释为什么推理引擎适合嵌入应用"
}],
"max_completion_tokens": 128
}),
&cancellation,
|_token, text| {
print!("{text}");
io::stdout().flush().is_ok()
},
)?;
println!("finish={} completion={}",
result.finish_reason, result.completion_tokens);
Ok(())
}
图像输入仍然使用同一个接口,只需要把 user content 改成有序的图文 part。本地路径、HTTP(S) URL 和 data URL 会走同一套图像物化与视觉编码路径;Gemma 4 E4B 的 mmproj 在第一次图片请求时懒加载,因此纯文字启动不会先付出视觉塔的装载成本。
模型与运行方式
本文使用:
- Gemma 4 E4B instruction-tuned GGUF
- 主模型:Q4_K_M,约 4.98 GB
- 视觉投影:mmproj-F16.gguf,约 990 MB
只想在终端立即体验时,不需要 YAML 或服务:
bash
cargo build --release --bin zllm-metal
./target/release/zllm-metal ./models/gemma-4-E4B-it-GGUF/gemma-4-E4B-it-Q4_K_M.gguf
程序会从 GGUF metadata 识别架构、发现同目录 mmproj、推导 KV 预算与上下文,然后装载 Metal runtime,进入多轮终端对话并复用 KV Cache。输入本地图片路径或使用 /paste,即可进行视觉理解。
MacBook Air M5 真机结果
以下数据来自同一台 24 GB MacBook Air M5 和同一份 Q4_K_M 权重,不是理论估算:
| 项目 | 实测结果 |
|---|---|
| zllm-metal release 文件 | 8.1 MB |
| CLI 自动上下文 | 49,152 token |
| 模型加载(本地热文件缓存,多次启动) | 0.9--1.6 秒 |
| 文本 tg50,三次冷启动均值 | 40.47 token/s |
| 同一 115-token 回复全段 decode | 38.1--38.5 token/s |
| 323-token 图文请求 prefill | 6.469 秒 |
| 同一图文请求 TTFT | 7.312 秒 |
速度会随模型版本、上下文、采样参数、文件缓存和机器散热状态变化。演示验证的是模型装载、文字对话和视觉输入的完整调用链,不是模型精度评测。
最重要的不是 8 MB
真正值得关注的是交付边界:模型执行成为应用的一部分------一个 Rust 对象、一份模型、一个原生 backend。对于 Rust 开发者,"给现有程序增加本地 AI"不再是一次服务部署,而是一次普通的库调用。
zLLM 代码仓库即将上线。完整配置、模型下载链接和 23 秒真机演示见原文: