Docker跑Ollama配GPU:compose写法、环境变量默认值,和悄悄掉回CPU的显存账

2026-10-22 约 28 分钟阅读

容器能应答第一条提问,接着掉到每秒四个token,不是硬件慢,是模型被拆到GPU和CPU两边而且不报错。设备预留那一段、从源码读出的环境变量默认值,以及能提前算出OOM的显存账。

💡 你将学到

容器能应答第一条提问,接着掉到每秒四个token,不是硬件慢,是模型被拆到GPU和CPU两边而且不报错。设备预留那一段、从源码读出的环境变量默认值,以及能提前算出OOM的显存账。

📜 目录

容器启动正常,第一条提问有回复,接着掉到每秒四个token——这不是性能问题。模型被拆到GPU和CPU两边了,屏幕上没有任何提示。镜像没法告诉你GPU根本没挂上,只能自己去问。

下面这套配置能跑通,环境变量默认值取自envconfig/config.go,显存账算清楚,免得等到OOM才发现。

先证明容器里看得见GPU

ollama/ollama镜像自带CUDA和ROCm库,但不带驱动。NVIDIA主机上先装Container Toolkit:配源、apt-get install -y nvidia-container-toolkit、sudo nvidia-ctk runtime configure --runtime=docker、重启docker。然后一行冒烟测试:docker run --rm --gpus=all ollama/ollama nvidia-smi -L。这行没输出,后面拉什么模型都在CPU上跑。

两个变体:AMD跳过toolkit,用rocm标签并透传--device /dev/kfd --device /dev/dri;Jetson板子探测不到JetPack版本,要显式给JETSON_JETPACK=5或6。Vulkan已内置,容器能看到设备就默认启用,OLLAMA_VULKAN=0关闭,GGML_VK_VISIBLE_DEVICES指定设备。

compose里最关键的那一段

把设备预留写进服务:deploy.resources.reservations.devices,driver选nvidia、count为all、capabilities写gpu。这就是--gpus=all的compose v2写法。漏掉这一段,容器照样启动、照样应答,只是静悄悄全走CPU——「Docker里Ollama很慢」的报障多数出在这一处。同时把OLLAMA_KEEP_ALIVE设成30m、OLLAMA_CONTEXT_LENGTH显式写成32768、OLLAMA_MAX_LOADED_MODELS设1,健康检查用ollama list。

默认值清单(实测自二进制)

OLLAMA_HOST默认127.0.0.1:11434;OLLAMA_MODELS默认~/.ollama/models,容器内是/root/.ollama/models;OLLAMA_KEEP_ALIVE默认5分钟,负值表示常驻;OLLAMA_LOAD_TIMEOUT默认5分钟;OLLAMA_NUM_PARALLEL默认1;OLLAMA_MAX_LOADED_MODELS默认0(自动);OLLAMA_MAX_QUEUE默认512;OLLAMA_CONTEXT_LENGTH默认0(自动);OLLAMA_FLASH_ATTENTION默认关闭;OLLAMA_KV_CACHE_TYPE默认f16;OLLAMA_GPU_OVERHEAD默认0字节;OLLAMA_MAX_TRANSFER_STREAMS默认4。KEEP_ALIVE那5分钟正是「聊两句很快、隔一会儿再问又变慢」的原因。

上下文长度是被替你决定的,而且偏小

Ollama按可用显存自动选上下文:不到24GiB给4096 token,24到48GiB给32768,48GiB以上给262144。16GB的卡只有四千token记忆,写代码、跑agent、长文档提问会被悄悄截断,症状是「模型忘了前面的要求」。官方建议agent与编码类任务至少给64000。另有一个改不动的上限:请求超过模型训练长度时,服务端记一条requested context size too large for model并把num_ctx压回训练长度,调参数调不过这个天花板。

显存怎么算

两部分:权重文件和K/V缓存。默认标签的权重大小实测:qwen3:8b 5.23GB、llama3.1:8b 4.92GB、qwen3:14b 9.28GB、gemma3:12b 7.31GB另加0.85GB视觉投影层。K/V缓存按每个token算:2(K和V)×层数×KV头数×head_dim×每元素字节。Qwen3-8B是36层、8个KV头、head_dim 128,f16下每token 147456字节即144KiB,4096token约576MiB,32768token约4.5GiB,65536token约9GiB。Llama-3.1-8B是32层,每token 128KiB,32k约4GiB。都是8B参数,缓存差12%,差别在层的几何结构,不在参数量。Gemma3-12B按公式算是每token 384KiB,但它有滑窗注意力层,真实占用低于公式,按最坏情况算不会翻车。

还要乘OLLAMA_NUM_PARALLEL,每个并发槽位分配自己的上下文窗口。Qwen3-8B在32k下开两个并发就是9GiB缓存加5.23GB权重,16GB卡掉到40%CPU就是这么来的。

留1GB给驱动和CUDA上下文之后的实用预算:12GB卡跑qwen3:8b开8k,6.4GB,很快;16GB卡跑qwen3:8b开32k,9.7GB,宽裕;16GB卡跑qwen3:14b开32k,13.8GB,紧,不能并发;24GB卡跑qwen3:14b开64k,18.3GB,并发只能设1。

看PROCESSOR,不只看回答

docker exec ollama ollama ps输出里PROCESSOR这一列是关键。100% GPU表示权重和缓存全部驻留;出现类似62%/38% CPU的分裂,就是OOM警告已经生效了——装载器留下装得下的部分,其余塞进内存,不会报错。同一行还显示实际分配的CONTEXT,用来抓被截断的默认值。容器外想看JSON,curl -s localhost:11434/api/ps返回同样字段。

按这个顺序改

先证明容器里GPU可见;把上下文长度显式钉住,别信显存启发式;KEEP_ALIVE设得比流量间隔长;NUM_PARALLEL在量过缓存成本之前保持1。其余都是调优,这四项决定部署能不能用。

常见问题

官方镜像自带CUDA吗?

自带CUDA与ROCm运行库,但带不了宿主机驱动和容器运行时钩子,所以NVIDIA主机上Container Toolkit那一步是必须的。

为什么ollama ps里有我没要的CPU比例?

权重加缓存没都装下。装载器把剩下的放到内存里继续跑,用延迟换「至少能跑」,全程不报错,PROCESSOR是唯一信号。

量化K/V缓存有用吗?

OLLAMA_KV_CACHE_TYPE默认f16。换成更窄的精度能压上面公式里的数字,代价是输出质量。要换就先在自己的prompt上量质量损失,显存不够优先换更小的模型。

能同时跑两个模型吗?

两个都得装得下。两个8B模型各开32k,光权重加缓存就超过19GB。单卡上通常一个模型配更长keep-alive更划算。

相关文章
2026-10-20
2026哈利法克斯AI外勤服务软件:跨港调度与HST开票怎么测
2026-10-19
2026哥本哈根AI报关单证工具怎么选:EORI、ICS2与归类这条红线
2026-10-19
2026商业地产AI租约提取软件:该比的是条款覆盖,不是字段数量
2026-10-20
2026伯尔尼AI费用管理软件:8.1%增值税、纸质票据与托管会计能用的报表
2026-10-22
2026教师AI出卷工具:五款工具,看答案与批改怎么落地
2026-10-22
2026 LangChain RAG教程:chains模块消失后,管线怎么重写

本站文章由编辑人工撰写,收录的工具均经过实测或公开资料核验。文中链接指向工具官网或 GitHub 仓库,仅作信息参考,不构成付费推广。

💬 评论 (0)

暂无评论,来说两句吧~

登录后评论