从 Ollama 到 llama.cpp:视觉模型的返璞归真
绕了一大圈,结论就是几行参数的事
2026-05-26 更新: 现在回归到纯粹的 llama.cpp,Ollama 已删除,不再需要它的额外开销
起因
Ollama 用得好好的,qwen3-vl-4b 日常识图也够用
直到某天我想试试去审查版(abliterated),发现 Ollama 官方没有这个版本,只能手动下 GGUF
那就下呗——然后发现 Ollama 加载自定义 GGUF 各种不方便,模型文件管理也乱七八糟
于是动了自己搭的念头
第一步:下模型
看上了三个视觉模型:
- Qwen2.5-VL-7B — 视觉编码很细(patch14 + 32层ViT),但 LLM 部分弱(28层4头)
- Qwen3-VL-8B — 新架构,LLM 强(36层8头),视觉稍粗(patch16 + 27层)
- bge-m3 — 嵌入模型,给后面 RAG 用
从 hf-mirror.com 下 GGUF
还好镜像站支持断点续传,不然几个 G 的文件断了重下真要命
第二步:on-demand relay
显存只有 12GB,桌面占 1GB,Ollama 常驻占 4GB,剩 6GB 左右
跑一个 VL 模型还行,同时跑多个肯定炸
解决方案是写个 Python relay:启动时只开个 HTTP 端口等着,有请求才拉起 llama-server,空闲 300s 后杀掉进程释放显存
用了 ctypes prctl 做进程陪葬(pdeathsig),防止 relay 意外退出后子进程变孤儿
效果不错,但代码 180 行,看着就烦
第三步:发现 —sleep-idle-seconds
后来看 llama-server 帮助才发现有个 --sleep-idle-seconds N 参数:空闲 N 秒后自动卸载模型权重,新请求自动加载
这就完全不需要 relay 那套轮询杀进程了
试了一下,30 秒空闲后 VRAM 从 7GB 掉到 960MB,新请求 1.4 秒自动唤醒
于是 relay 代码可以扔了,换成一行 exec:
exec llama-server \ -m model.gguf --mmproj mmproj.gguf \ --port 8087 \ -ngl 99 \ --sleep-idle-seconds 30第四步:借鉴参数
豆姐给了一套优化参数,对比之后调整了:
| 参数 | 原来 | 现在 | 说明 |
|---|---|---|---|
-ngl | 99(全GPU) | 99 | 不让CPU拖后腿 |
--cache-type-k/v | q8_0 | q4_0 | KV缓存减半,视觉单轮无影响 |
--no-cache-prompt | 无 | ✓ | 用完即刻清KV缓存,不等30s |
--no-cache-idle-slots | 无 | ✓ | 同上 |
调整后推理显存从 7.4GB 降到 6.4GB(纯 llama.cpp 无 Ollama),速度反而没降
验证:8B vs 4B
用一张实验板书照片做对比:
4B: 识别出基本内容,但漏了副标题,实验原理里的「乙醚」误读成「氯仿」
8B: 完整读出所有中文字符,自动分节(目的→原理→步骤),每一步不光读出来还解释了化学原理(加生石灰是为了中和酸性物质、吸水)
连底部相机参数都认出来了
结论:视觉编码细一点不如 LLM 强一点实在
最终形态
每个模型一个 sh 文件,cd ~/AI-Server && ./qwen3-vl-8b 启动,Ctrl+C 停止
十二行,没有多余层:
#!/usr/bin/env bashexec llama-server \ --model model.gguf --mmproj mmproj.gguf \ --port 8087 --host 127.0.0.1 \ -c 8192 -ngl 99 -t 8 \ --cache-type-k q4_0 --cache-type-v q4_0 \ --no-cache-prompt --no-cache-idle-slots \ --cont-batching --parallel 1 \ --no-warmup --sleep-idle-seconds 30从 Ollama → Python relay → exec sh,从 180 行 → 12 行,从 7.4GB → 6.4GB
返璞归真
不过为这破事搞的 GitHub 仓库优化参数,现在内置参数一行搞定
感觉白搞了
挺好,下次继续
😅
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时
