Ollama GPU 与性能优化
模型跑得慢,九成的原因能在一行 ollama ps 里找到线索。本章节从排查方法讲到硬件支持、多卡分配,再到 Flash Attention 与 KV 缓存量化两个进阶开关。
目标只有一个:让你的显卡物尽其用。
第一步永远是:确认模型跑在哪
性能排查的第一动作是看 PROCESSOR 列,它直接告诉你模型 weights 装在了哪里。
$ ollama ps
NAME ID SIZE PROCESSOR CONTEXT UNTIL
qwen3.5:27b a8b2c9d3e4f5 20.4GB 52%/48% CPU/GPU 4 minutes from now三种形态对应完全不同的处境:
| PROCESSOR 显示 | 含义 | 速度预期 |
|---|---|---|
| 100% GPU | 全部权重装入显存 | 显卡满血速度 |
| 100% CPU | 显存完全装不下,纯内存推理 | 慢一到两个数量级 |
| 52%/48% CPU/GPU | 显存不足,权重被切分 | 明显下降,卡在跨设备传输 |
配合生成速度一起看更直观:API 响应尾部的 eval_count / eval_duration * 10^9 就是 token/s(用法见 API 章节的后文),把这个数字作为每次优化的量化标尺。
遇到慢模型,按下面的决策路径走:
各平台 GPU 加速支持
Ollama 支持四大加速后端,装对驱动是前提。
| 平台 | 后端 | 要求 |
|---|---|---|
| NVIDIA | CUDA | 计算能力 5.0 以上,驱动 550+(5.0~6.2 老卡需 570+) |
| AMD(Linux) | ROCm v7 | 需要 ROCm v7 驱动,老驱动会导致发现超时回退 CPU |
| AMD(Windows) | ROCm v7 / Vulkan | ROCm v7 或 HIP7 驱动栈;部分 RX 6000 系用 Vulkan 兜底 |
| Apple Silicon | Metal | 开箱即用,无需任何配置 |
| Intel / 其他 | Vulkan | 默认启用的补充后端,覆盖 AMD 老卡与 Intel 显卡 |
排查 GPU 是否被识别,看日志里的发现记录最有说服力;NVIDIA 用户也可以用 docker run --gpus all ubuntu nvidia-smi 验证容器场景的直通。
想限制 Ollama 只用某几块卡,或者强制纯 CPU,各后端有对应开关:
实例
# NVIDIA:只让 Ollama 用第一块卡(推荐用 UUID,nvidia-smi -L 查看)
CUDA_VISIBLE_DEVICES=GPU-xxxx ollama serve
# AMD:同理用 ROCr 设备列表
ROCR_VISIBLE_DEVICES=0 ollama serve
# Vulkan:指定设备序号
GGML_VK_VISIBLE_DEVICES=1 ollama serve
# 三种写法的"-1"均表示禁用 GPU,强制纯 CPU
CUDA_VISIBLE_DEVICES=-1 ollama serve多 GPU 负载分配
多卡机器的分配策略是自动的,规则只有一条:优先单卡,装不下才切分。
模型能完整装进任意一块卡时,Ollama 会选一块装下——单卡避免了跨 PCIe 的数据搬运,通常是吞吐最优解。
单卡装不下时,模型会被切分到所有可用卡上;此时还要给 KV 缓存和上下文留出余量,这也是大参数模型"明明总显存够却还是切分"的常见原因。
Linux 上多块 AMD 卡混用时,个别驱动版本可能出现乱码输出,这类问题在 AMD 官方的多卡已知问题文档中有记录,优先升级 ROCm 驱动。
CPU 推理的优化空间
没有独显也能跑,但有几个能榨则榨的点。
Ollama 自带多套 CPU 推理库,性能排序为 cpu_avx2 优于 cpu_avx 优于 cpu,默认自动选择;自动探测失灵时可以强制指定:
实例
# 强制使用 AVX2 推理库
OLLAMA_LLM_LIBRARY=cpu_avx2 ollama serve
# 确认自己的 CPU 支持哪些指令集
cat /proc/cpuinfo | grep flags | head -1两个额外事实:macOS 的 Rosetta 转译环境只能使用基础 cpu 库;线程数由 options 中的 num_thread 控制,默认取物理核数,盲目调大反而会因为超线程竞争变慢。
CPU 推理的隐性大头是上下文长度:同样的模型,4K 上下文与 32K 上下文的 CPU 推理速度差异非常明显。给 CPU 场景配模型时,不要随手把 num_ctx 设很大。
Flash Attention 与 KV 缓存量化
这两项是长上下文场景最重要的显存优化,它们作用的对象不是模型权重,而是随上下文增长的 KV 缓存。
新版 Ollama 在后端支持时会自动启用 Flash Attention,也可以用变量强制开关:
实例
# 强制开启 Flash Attention
OLLAMA_FLASH_ATTENTION=1 ollama serve
# KV 缓存量化为 8 位:显存减半,精度几乎无损(推荐)
OLLAMA_KV_CACHE_TYPE=q8_0 ollama serve| KV 缓存类型 | 显存占用 | 质量影响 | 建议 |
|---|---|---|---|
| f16(默认) | 基准 | 无损 | 显存充裕时保持默认 |
| q8_0 | 约一半 | 几乎无感 | 长上下文场景的推荐选择 |
| q4_0 | 约四分之一 | 长上下文下可感知 | 极限压榨时再考虑 |
两个注意点:KV 缓存类型是全局配置,对所有加载的模型生效;量化对质量的影响因模型而异,部分高 GQA 结构的模型敏感度更高,切换后建议用固定 seed 的提示词对比验证。
量化精度与速度的质量权衡
模型选型章节讲过量化的体积收益,这里补上速度视角的几个结论。
| 精度 | 体积 | 速度 | 质量 | 适用 |
|---|---|---|---|---|
| q8_0 | 约 fp16 的一半 | 与 fp16 接近 | 几乎无损 | 显存充裕的优选 |
| q4_K_M | 约 fp16 的四分之一 | 通常更快 | 小幅下降 | 本地部署默认档 |
| q4_K_S 及更低 | 更小 | 不一定更快 | 下降更明显 | 极限省显存 |
反直觉的一点:更低的量化不一定更快。推理速度受内存带宽制约,部分低比特格式需要额外的反量化计算,实测可能持平甚至更慢,选量化档位不要只看数字。
建议的对比方法:固定 seed 和同一组提示词,在 0.3 低温下对比两个量化档位的输出与 token/s,质量和速度一起看。
并发与吞吐调优
单请求优化到头之后,下一步是让服务吃得下并发。
核心变量是 OLLAMA_NUM_PARALLEL(单模型并行请求数),代价必须牢记:并行处理会把上下文缓存按倍数复制,所需显存约等于 该值 × 上下文长度 的 KV 空间,设大了模型可能被挤出 GPU。
服务端的排队由 OLLAMA_MAX_QUEUE 控制,默认 512,超过直接返回 503,客户端要做重试。
吞吐调优的操作顺序:
第一步,单请求调优(规格、量化、FA 与 KV 缓存)确认单路速度。
第二步,逐步调大 NUM_PARALLEL,每档都用 ollama ps 确认仍是 100% GPU,观察总吞吐是否上升。
第三步,出现排队 503 或混合切分时回退一档,那是显存的红线。
AI 思考中...