blog
•
2026年9月17日
•
11 次阅读
用 GTX 1060 跑 llama.cpp:把 2B 小模型变成我的免费外包工
tech
ai
## 起因:能自己干的活,别都花钱外包
我的自建 Agent 平时跑在云上的大模型上,好用,但每一句话都是钱。日常真正费 token 的其实不是"难问题",而是机械活:把一段文本里的字段抠成表格、把日志压成几句话、给脚本起个骨架、粗翻一段外文。这些活对模型能力要求不高,对"能不能顺手调起来"要求很高。
家里那台老主机(i5-9400F + GTX 1060 6G)平时就给语音合成和音频转写当后端,GPU 大部分时间闲着。既然卡空着,就让它在本地扛一部分推理——免费、离线、数据不出门。
## 选型:Pascal 老卡的三条铁律
GTX 1060 是 Pascal(compute 6.1),放今天确实老了,但跑小模型完全够。选型上有三条硬约束,踩过才知道:
1. **只认 GGUF 的 Q4/Q5 量化**。Pascal 不支持 FP8/FP4/NVFP4,花哨的低比特格式这条路直接封死。
2. **7-9B 在 6G 显存上很勉强**。Q4 大概 4.5-5.5GB,再加 KV cache,得限上下文或者把一部分层丢给 CPU。
3. **甜点区是 ≤4B,尤其 MoE**(总参数大、激活少,对显存和算力都友好)。
推理框架没犹豫,llama.cpp:单文件部署、CUDA 后端成熟、GGUF 生态最全,不用跟 Python 环境纠缠。
模型最后选 **MiniCPM5-2B**(Q4_K_M,1.45GB)。2B 这个量级在这张卡上留足了上下文空间,实测确实够用。
## 安装:真正的坑不在 llama.cpp
### 1. 工具链
```bash
sudo apt-get install -y cmake ninja-build build-essential
```
cmake 3.31.6 / ninja 1.12.1 / g++ 14.2.0。
### 2. 源码——GitHub 直连不通
这台机器直连 github.com 是死的。绕法:在另一台能上外网的机器(家里那台迷你主机开着代理)上克隆,打包传过来。
```bash
# 在代理机上
https_proxy=http://127.0.0.1:7892 git clone --depth 1 https://github.com/ggml-org/llama.cpp
tar czf llama.tar.gz llama.cpp
# 传过去
scp llama.tar.gz monika@192.168.1.88:/home/monika/llama/
```
代价是 tarball 里没有 `.git`,`llama-cli --version` 会显示 `commit unknown`——不影响使用,但版本号得自己记(本次是 `fb27a525`)。
### 3. CUDA
```bash
sudo apt-get install -y nvidia-cuda-toolkit
```
Debian 仓库里就是 **12.4.131**,跟驱动 550.163 对得上。装完 `nvcc --version` 有输出就行。顺带一提这包很"实在"——174 个依赖,连着 AMD HIP、OpenCL、Nsight 一起塞进来,1.2GB。
### 4. 编译——这里有个必踩的坑
```bash
cmake -B build -G Ninja \
-DGGML_CUDA=ON \
-DCMAKE_CUDA_ARCHITECTURES=61 \
-DCMAKE_CUDA_HOST_COMPILER=/usr/bin/g++-13
cmake --build build -j4 --target llama-cli llama-server llama-bench
```
两个关键参数:
- `CMAKE_CUDA_ARCHITECTURES=61`:给 Pascal 编译,别用默认的新架构。
- **`CMAKE_CUDA_HOST_COMPILER=/usr/bin/g++-13`**:CUDA 12.4 不认识 g++ 14,不显式指定的话编译直接炸。g++-13 是装 toolkit 时顺带进来的,正好用上。
364 个目标,4 核老 U 上跑了 8 分钟。
## 实测:数字比感觉重要
模型:`MiniCPM5-2B-Q4_K_M.gguf`(1.45GB,sha256 核对过)
| 配置 | Prompt | 生成 |
|---|---|---|
| GPU(`-ngl 99`,全量上卡) | 453.8 t/s | **58.6 t/s** |
| CPU(`-ngl 0`,对照) | 45.8 t/s | 8.0 t/s |
**生成快 7.3 倍,prompt 快 10 倍**。58 t/s 什么概念:比正常阅读速度快得多,当"外包工"完全不会拖节奏。
也能从日志里确认它真的跑在 GPU 上(不是"编译通过"就算):
```
llama_prepare_model_devices: using device CUDA0 (NVIDIA GeForce GTX 1060 6GB) - 3619 MiB free
load_tensors: layer 0..41 assigned to device CUDA0
```
### 显存账(6G 卡的边界)
| 项 | 占用 |
|---|---|
| 模型 + 计算缓冲(4k 上下文) | 约 1.34G + 52M |
| 32k 上下文时的 llama-server | 2838 MiB |
| 常驻的语音合成服务 | 2380 MiB |
| 合计 | **5218 / 6144 MiB** |
32k 上下文已经把这 6G 用掉 85%,余量 900M 左右——再多就得跟语音服务抢卡。想上 64k,只能先把语音停掉。
## 一个没想到的坑:思考模型
MiniCPM5 默认开着"思考"。后果是:**它把整段思路塞进 `reasoning_content`,`content` 字段留空**——512 tokens 都不够它把想法写完,客户端看过去就是"模型没回话"。
关掉就好:
```json
{"chat_template_kwargs": {"enable_thinking": false}}
```
关掉之后 `reasoning_content` 长度为 0,`content` 直接给出干净答案,`finish_reason: stop`。对"干活"这种场景,思考链除了烧 token 没有任何好处。
## 怎么用:免费外包工 + 人工审查
现在它是一个常驻服务,OpenAI 兼容接口落在 `0.0.0.0:9882`(9880 给语音、9881 给转写),开机自启跟着其它服务一起拉起来:
```bash
curl http://192.168.1.88:9882/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"messages":[{"role":"user","content":"...你的任务..."}],"max_tokens":2048}'
```
定位很明确:**它只省 token,不省脑子**。我给它的边界是机械、可复查的活——批量抽取、分类、粗翻译、格式转换、脚本骨架、日志摘要;需要长期上下文、需要判断、以及任何敏感内容,都不交给它。
每份产出我都会自己过一遍再往外发。实测两把很能说明水平:
- 把「人名 + 日期 + 事件」抽成 markdown 表格:**一次就对**,三行全准。
- 「去重并升序」:**错了**,`['2026-09-13','2026-09-13','2026-09-14','2026-09-14','2026-09-15']`,重复项原样留着。
2B 就是 2B。用对地方,它是白捡的算力;用错地方,省下的 token 会以双倍还回去。
## 小结
- 老硬件 + 小模型 + llama.cpp,到今天依然是性价比很高的一条路:一张 Pascal 时代的 6G 卡,跑 2B 模型能有 58 t/s。
- Pascal 的三条铁律(GGUF Q4/Q5、≤4B 或 MoE、7-9B 要省着用)先记牢,能省掉一半试错。
- 真正花时间的不是模型,是环境:代理绕行、CUDA 版本与编译器的兼容性。
- 思考模型在"干活"场景下记得把思考关掉,别让答案淹在 `reasoning_content` 里。
- 定位永远是"外包工":不要求它一次做对,只要求它做那些"错了我也能立刻看出来"的活。