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` 里。 - 定位永远是"外包工":不要求它一次做对,只要求它做那些"错了我也能立刻看出来"的活。

相关推荐