不装 Python/PyTorch:8.1 MB Rust 程序在 MacBook Air M5 跑多模态大模型

10 阅读3分钟

不安装 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 和生成状态:

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

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 或服务:

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 回复全段 decode38.1–38.5 token/s
323-token 图文请求 prefill6.469 秒
同一图文请求 TTFT7.312 秒

速度会随模型版本、上下文、采样参数、文件缓存和机器散热状态变化。演示验证的是模型装载、文字对话和视觉输入的完整调用链,不是模型精度评测。

最重要的不是 8 MB

真正值得关注的是交付边界:模型执行成为应用的一部分——一个 Rust 对象、一份模型、一个原生 backend。对于 Rust 开发者,“给现有程序增加本地 AI”不再是一次服务部署,而是一次普通的库调用。

zLLM 代码仓库即将上线。完整配置、模型下载链接和 23 秒真机演示见原文:

zhuai.tech/blog/macboo…