File size: 4,803 Bytes
e85df1f 3b0a4b4 e85df1f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | ---
language:
- zh
- en
tags:
- gpu
- ollama
- metal
- local-inference
- llm
- rust
license: mit
pretty_name: perch-gpu — Local GPU Acceleration Toolkit
---
> ⭐ **这是栖木 Perch 的开源组件之一。**
> 核心应用(macOS 本地优先 AI 工作台 · 0.08s 首字)在这里 →
> [**🪵 栖木 Perch**](https://huggingface.co/datasets/hongcoding/perch)
# 🖥️ perch-gpu
### 让本机大模型真的用上 GPU——而且用得对。
> 你装了个 7B 模型,满心期待地点发送。
> 然后**等了 5 秒**才出第一个字。
>
> 你查了半天,以为是模型太大、显卡太弱。
> 其实——**是 Ollama 把它从显存里卸载了**。
**perch-gpu** 是一个 Rust 工具箱,解决本机大模型 GPU 加速的三个坑。
从 [栖木 Perch](https://huggingface.co/datasets/hongcoding/perch) 生产环境提取 · MIT · `cargo test` 全绿
---
## 🕳️ 三个坑(大多数人都踩了)
### 坑 1 · 强行指定 GPU 层数
```json
{ "num_gpu": 40 } // ❌ 错
```
很多人以为这样能"控制 GPU 加速"。实际后果:
**Ollama 触发 runner 重载 → 反而更慢。**
**正确做法**:让 Ollama 自己按模型结构和显存选择后端与层数。
你只需要**如实报告**它分配了多少——这就是本库的 `status` 模块。
### 坑 2 · 模型被悄悄卸载
Ollama 默认在空闲后释放显存。下次请求**冷加载 3~5 秒**——
比云端还慢,你的"本机秒回"名存实亡。
**正确做法**:预热一次 + `keep_alive` 保活。
本库的 `warmup` 模块,首 token 从 3s 降到 **0.04~0.18s**。
### 坑 3 · 本机并发抢显存
同时跑两个模型?一块 GPU 会互相拖慢,甚至 OOM。
**正确做法**:本机并发压到 1(排队比抢显存快),云端可控并发。
本库的 `scheduler` 模块。
---
## 🚀 快速开始
```toml
[dependencies]
perch-gpu = { git = "https://huggingface.co/hongcoding/perch-gpu" }
```
```rust
use perch_gpu::{status, warmup, scheduler};
// 1) 预热 + 保活 30 分钟(首 token 从 3s 降到 0.08s)
warmup::warmup_model("qwen3-06b:latest", "30m", None).await?;
// 2) 查真实 GPU 驻留(读 Ollama /api/ps,不是猜)
let st = status::query_status(None).await?;
for m in &st.models {
println!("{} → GPU 驻留 {}%", m.name, m.gpu_residency_percent);
}
// 3) 本机推理排队(并发 1,防止抢显存)
let _permit = scheduler::acquire(false).await?;
// ... 跑推理 ...
```
跑 demo 看效果:
```bash
cargo run --example gpu_status
```
真实输出:
```
🔍 查询本机 GPU 状态(http://127.0.0.1:11434)…
📦 qwen3-06b:latest
GPU 驻留: 100%(0.37GB / 0.37GB)
上下文: 4096
过期: 2026-11-05T22:30:00+08:00
✅ GPU 加速正在生效(Ollama 已自动选择 Metal/CUDA 后端)
```
---
## 🧩 三个模块
| 模块 | 作用 | 关键点 |
|---|---|---|
| **`status`** | 读 Ollama `/api/ps` 真实 VRAM 分配 | 驻留百分比来自真实字节,不是估算 |
| **`warmup`** | 预热 + `keep_alive` 保活 | **绝不传 `num_gpu`**(会触发重载)|
| **`scheduler`** | 本机/云端资源调度 + 元数据缓存 | 只控并发度,不改语义 |
## 📊 实测效果(栖木 Perch,Apple Silicon + Metal)
| 状态 | 首 token 延迟 |
|---|---|
| 冷加载(模型被卸载) | **3 ~ 5 秒** |
| 热驻留(预热 + 保活) | **0.04 ~ 0.18 秒** |
**快 20~70 倍**,代价只是让 0.6B 模型占着 ~0.4GB 显存。
---
## 🛡️ 设计红线
| 红线 | 原因 |
|---|---|
| **绝不传 `num_gpu`** | 让 Ollama 自己选,强行指定会重载 |
| **诊断不猜** | 驻留百分比 = 真实 `/api/ps` 字节数 |
| **调度不改语义** | 只控并发,不碰模型/prompt/思考档/回复长度 |
| **预热不出本机** | 预热提示只发 loopback,不进对话历史 |
## 🔬 验证
```bash
cargo test # 7 个单元测试 + 1 个文档测试
```
覆盖:真实驻留计算 / CPU 回退 / 无模型 / 预热体不含 num_gpu / 并发序列化 / 缓存失效。
---
## 🔗 相关项目
| 项目 | 说明 | 链接 |
|---|---|---|
| **栖木 Perch**(应用) | macOS 本地优先 AI 工作台 | https://huggingface.co/datasets/hongcoding/perch |
| **perch-ultrafast**(框架) | 混合流 + Ultrafast 推理框架:首字 1s → 80ms | https://huggingface.co/hongcoding/perch-ultrafast |
| **perch-gpu**(本库) | 本机 GPU 加速工具箱 | https://huggingface.co/hongcoding/perch-gpu |
| **HF Collection** | 全部归在一起 | https://huggingface.co/collections/hongcoding/perch-ai-workbench-and-ultrafast-framework |
## 📜 许可
MIT —— 随便用,注明出处即可。
---
**🖥️ 别让你的 GPU 闲着。也别让 Ollama 偷偷把它卸载。**
|