GGUF 本地部署实操:llama.cpp 与 Ollama 两条路径
更新于 2026-09-10 · 核实于 2026-09-10
下载一个 GGUF 文件、跑起来、看一眼速度——听起来三步的事,卡住大多数人的是中间没说清的部分:一排量化文件名选哪个、-ngl 到底设多少、为什么「能跑」但慢得像打字机。这篇把 llama.cpp 和 Ollama 两条路径从头到尾走一遍,每个数字都给出算法,跑完之后怎么验证也讲清楚。
动手之前:先算显存
错误的顺序是「先下载,装不下再说」。一个 70B 的 Q4 文件 43GB,下到一半才发现装不下,浪费的是一小时带宽。正确的第一步是算账。本站显存计算器用的公式:
总显存 = 参数量(十亿) × bit/权重 ÷ 8 ← 权重,≈ GGUF 文件体积
+ KV 缓存(随上下文线性增长)
+ 约 1.5GB 运行时开销
bit/权重取实测 GGUF 文件反推值:Q4_K_M 约 4.9、Q6_K 约 6.6、Q8_0 约 8.5。按 8K 上下文、fp16 KV 缓存算几个常见组合:
| 模型 × 量化 | 权重 | KV @8K | 总量 | 能装下的卡 |
|---|---|---|---|---|
| Llama-3.1-8B Q4_K_M | 4.9GB | 1.1GB | 7.5GB | RTX 3060 12GB,宽裕 |
| Llama-3.1-8B Q8_0 | 8.5GB | 1.1GB | 11.1GB | 12GB 勉强,16GB 宽裕 |
| Qwen3-32B Q4_K_M | 20.1GB | 2.1GB | 23.7GB | 单张 24GB(3090/4090),勉强 |
| Llama-3.3-70B Q4_K_M | 43.2GB | 2.7GB | 47.4GB | 2× 24GB 或 48GB 卡 |
| Qwen3-30B-A3B(MoE)Q4_K_M | 18.7GB | 0.8GB | 21.0GB | 单张 24GB |
判定标准:总量 ≤ 可用显存 80% 为宽裕,≤100% 为勉强。想在下载前确认自己的卡能跑哪个档,用显卡检查器直接查,它和本文是同一套公式。
量化档怎么选
Hugging Face 上 bartowski 等仓库的同一个模型会挂出一排文件:Q8_0、Q6_K、Q5_K_M、Q4_K_M、Q3_K_M……三条规则就够:
- 默认 Q4_K_M。 体积约 FP16 的 30%,对话和写作场景盲测基本分不出与 Q8 的差别。它是社区的默认档不是没有原因的。
- 显存富余就往上升: Q6_K、Q8_0。数学、长推理链、Agent 工具调用这类对权重噪声敏感的任务值得升档。
- Q4 到 Q3 是悬崖。 Q3_K_M 开始丢事实、前后矛盾;Q2 只剩「能出字」。装不下时的正确解法通常是换更小的模型,不是把大模型压到 Q2。完整对比见量化详解。
路径 A:llama.cpp
llama.cpp 是这一切的底层引擎——Ollama、LM Studio 都跑在它之上。从 GitHub releases 下载预编译包(或源码编译),得到 llama-cli、llama-server 等可执行文件。
下载 GGUF
两种方式:从 Hugging Face 页面手动下载对应档位的 .gguf 文件;或者直接用内置的 -hf 参数让 llama.cpp 自己拉:
llama-cli -hf bartowski/Meta-Llama-3.1-8B-Instruct-GGUF:Q4_K_M
8B 的 Q4_K_M 约 4.9GB,普通宽带几分钟。注意大模型的 GGUF 常拆成多个分卷,要全部下载放在同一目录。
三个关键参数
-ngl(—n-gpu-layers):放上显卡的层数。 这是 llama.cpp 最重要的参数,没有之一。-ngl 32 把 32 层全部上卡(Llama-3.1-8B 正好 32 层);-ngl 99 表示「能放多少放多少」,显存满了剩下的层自动落回 CPU 用系统内存跑——这就是部分卸载(partial offload),技术上完全可行,但生成速度会被拖到系统内存带宽档位:全量在 4090 上约 154 tok/s 的 8B Q4,部分卸载的下限只有个位数(理论估算 ±30%)。它适合「跑一夜看结果」的批量任务,不适合聊天。机制和决策边界见 CPU 卸载指南。
--ctx-size:上下文长度。 它直接决定 KV 缓存占多少显存。Llama-3.1-8B 开 8K 时 KV 约 1.1GB,开到 32K 涨到 4.3GB,总量从 7.5GB 变 10.7GB——本来宽裕的配置会变成顶格。显存吃紧时先想清楚自己到底需要多长上下文,别默认开满。
--cache-type-k q8_0 --cache-type-v q8_0:KV 缓存量化。 把 KV 缓存从 fp16 压到 8 bit,占用减半,质量损失极小。上下文吃紧时这是第一逃生通道,优先级高于降权重量化档。细节见 KV 缓存指南。
一条典型的完整命令:
llama-cli -m Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf -ngl 99 --ctx-size 8192
想要 API 服务而不是交互命令行,把 llama-cli 换成 llama-server,会起一个兼容 OpenAI 格式的本地接口。
启动日志就是验收单
llama.cpp 启动时会打印每一层的去向(GPU/CPU)、权重和 KV 缓存的实际 VRAM 分配。养成看一眼的习惯:日志里的分配值应该和你按公式估的总量对上量级;对不上,先查 --ctx-size 是不是和你假设的不一样。
路径 B:Ollama
Ollama = llama.cpp + 模型仓库 + 服务管理 + 自动更新。安装后一条命令:
ollama run llama3.1:8b
它会自动下载官方库里对应的 GGUF(默认通常是 Q4_K_M 档位)并进入交互会话。模型默认加载后驻留几分钟,空闲超时自动卸载。
导入自己的 GGUF
想用 Hugging Face 上的某个特定量化档,写一个 Modelfile:
FROM ./Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf
PARAMETER num_ctx 8192
然后 ollama create my-llama -f Modelfile 注册,ollama run my-llama 运行。
两个和 -ngl / —ctx-size 对应的参数
num_ctx(上下文):Ollama 的默认值是 4096(Modelfile 官方文档),比模型标称的上下文窗口小得多。这是「我按 8K 算的显存,怎么实测这么小」和「长文档为什么丢前文」两个高频问题的共同答案。交互会话里用/set parameter num_ctx 8192,或写进 Modelfile,新版本也支持环境变量OLLAMA_CONTEXT_LENGTH。num_gpu(上卡层数):等价于 llama.cpp 的-ngl,写进 Modelfile 如PARAMETER num_gpu 99。日常不用动——Ollama 默认会尽量全量上卡,装不下才自动部分卸载,而这个行为恰恰需要你主动去发现。
ollama ps:一眼看穿部署状态
ollama ps
输出里的 SIZE 是模型当前占用的显存+内存总量,PROCESSOR 是关键的一列:100% GPU 表示全量在卡上;出现 48%/52% CPU/GPU 这样的比例,说明部分层落到了内存——能跑,但速度会掉到个位数 tok/s。这条命令和 nvidia-smi 配合使用,是排查「为什么慢」的第一现场。
跑完之后:验证显存与速度
部署完成不等于部署正确。两个验收动作:
验证实际显存占用。 N 卡用 nvidia-smi 看进程占用;Ollama 用 ollama ps;llama.cpp 看启动日志的分配行。实测值和公式估算差得远时,按这个顺序排查:① 运行时默认上下文比你假设的小(Ollama 默认 4096);② KV 缓存被量化成了 q8;③ 部分层在内存里。
验证 tok/s。 llama.cpp 每轮生成结束会打印 eval time 和 tokens per second;Ollama 加 --verbose 标志,结束时会输出 eval rate。把实测值和理论估算对比——按本站速度模型:
理论 tok/s ≈ 显存带宽 × 0.75 ÷ 每 token 读取的权重 GB
参考锚点(理论估算 ±30%,实际受框架、驱动、CPU 影响):
| 硬件 | 模型 × 档位 | 理论速度【估】 |
|---|---|---|
| RTX 3060(360 GB/s) | 8B Q4_K_M | 约 55 tok/s |
| RTX 4090(1008 GB/s) | 8B Q4_K_M | 约 154 tok/s |
| RTX 3090(936 GB/s) | 32B Q4_K_M | 约 35 tok/s |
| 2× RTX 3090 | 70B Q4_K_M | 约 28 tok/s |
| RTX 4090 | Qwen3-30B-A3B(MoE,每 token 只读 2.0GB) | 约 374 tok/s |
实测在理论值的 0.7–1.3 倍区间里都算正常;差一个数量级,几乎必然是部分卸载了——回去查 ollama ps 或启动日志。另一个经验值:交互聊天低于约 10 tok/s 会明显烦躁,20+ 是流畅,这时该考虑降量化档、缩短上下文或换小模型。
常见误区
- 「下载了就跑,参数不用管。」 默认值到处埋雷:Ollama 的 num_ctx 默认 4096,长文档场景会在你不知情时截断;显存装不下时 Ollama 静默部分卸载,表现为「能跑但巨慢」。
- 「-ngl 设一半,速度减半而已。」 不是线性衰减,是断崖:只要最慢一环变成系统内存(60–100 GB/s),整个流水线按内存的节奏走,从三位数掉到个位数。
- 「显存占用应该约等于文件大小。」 文件 ≈ 权重,还要加 KV 缓存和约 1.5GB 开销。8B 模型开 128K 上下文时 KV 约 17GB,是 Q4 权重的三倍多。
- 「Ollama 和 llama.cpp 速度差很多。」 底层是同一个引擎,同模型同档位同参数下速度基本同源。差距来自参数默认值不同,不是引擎。
- 「tok/s 低就是卡不行。」 先看是不是部分卸载、上下文开满、或在跑 prefill 重的任务。纯解码速度由显存带宽决定,同一张卡上 Q4 一定比 Q8 快。
一句话结论
先用显存计算器算出能装下的最高量化档,下载 Q4_K_M 起步;llama.cpp 路线记住 -ngl 99 和 --ctx-size,Ollama 路线记住 num_ctx 和 ollama ps;跑完用启动日志和 tok/s 对照理论估算验收——对不上量级,九成是部分卸载了。
常见问题
llama.cpp 和 Ollama 该选哪个?
Ollama 底层就是 llama.cpp,速度基本同源。想省心选 Ollama:自带模型仓库、服务管理和 API。想完全掌控选 llama.cpp:每个参数(-ngl、上下文、KV 量化)都能显式指定,新特性也先到 llama.cpp。
llama.cpp 的 -ngl 应该设多少?
设为模型层数(如 Llama-3.1-8B 是 32 层)等于全量上显卡;设一个超过层数的大值(如 99)等于「能放多少放多少」,放不下的层自动落回 CPU。但部分卸载会让生成速度塌缩到系统内存带宽档位,只能当应急手段。
GGUF 文件名里一堆后缀,Q4_K_M、Q5_K_M、Q8_0 怎么选?
默认抓 Q4_K_M——体积约是 FP16 的 30%,质量在对话场景盲测难分。显存富余升 Q6_K 或 Q8_0,装不下才考虑 Q3。避开老式的 Q4_0 和激进的 IQ2/Q2 档,除非你知道自己在做什么。
为什么实际显存占用比 GGUF 文件大?
文件体积约等于权重显存,但运行还要加 KV 缓存和约 1.5GB 运行时开销。KV 缓存随上下文线性增长:Llama-3.1-8B 在 8K 上下文约 1.1GB,128K 时约 17GB。反过来,如果你按 8K 估的值比实测大,先查运行时的默认上下文——Ollama 默认只有 4096。
怎么确认模型全部跑在显卡上,没有偷跑到内存?
Ollama 用 ollama ps 看 PROCESSOR 列,「100% GPU」才是全量上卡,「48%/52% CPU/GPU」这类比例就是部分卸载;llama.cpp 看启动日志里每层的去向和 VRAM 分配行。部分卸载时 tok/s 会直接掉到个位数,速度本身就是最诚实的信号。