Ollama 在 Mac 上很慢?检查加载、上下文和内存
Ollama 变慢可能是模型仍在加载、提示词上下文很大、模型有一部分在 CPU 上运行,或者 Mac 处于内存压力下。这些情况需要不同的调整。删除已下载的模型可以释放磁盘空间,但不会自动让当前正在生成回答的模型变快。
将冷加载与第二次请求进行对比
保持模型、提示词和设置不变。先运行一个简短请求,然后在模型仍处于加载状态时重复该请求。如果只有第一次请求慢,可以先排查加载过程。如果两次生成都很慢,就调查执行和内存情况。记录对比结果,而不是把一次响应当作基准测试。
Ollama 的 API 文档会在完成的响应中提供独立的耗时字段,例如 load_duration、prompt_eval_duration 和 eval_duration。这些字段区分加载、读取提示词和生成输出。不要拿不同模型、上下文大小或提示词的 token 速率来比较,好像它们衡量的是同一个变化。
按阶段测量一个本地请求
对于使用常用端口的本地服务器,下面这个请求会返回一个 JSON 响应,让计时字段更容易检查。把 MODEL_NAME 替换成已在 ollama list 中安装好的本地模型;这次比较不要用云端模型。该请求会执行推理并消耗资源,但不会删除模型数据。
curl -sS http://localhost:11434/api/generate \
-H 'Content-Type: application/json' \
-d '{"model":"MODEL_NAME","prompt":"Explain what a file cache does in two sentences.","stream":false,"options":{"num_predict":128}}'
在模型保持加载的状态下再运行同一个请求。关闭流式输出后,终端会在响应完成后显示内容,所以这条命令是为了查看返回的计时字段,而不是靠肉眼给首个 token 计时。如果请求失败,保留它的错误并停止比较,不要把缺失的字段当作零。
| 返回字段 | 如何使用 |
|---|---|
load_duration |
比较首次加载和重复加载的时间 |
prompt_eval_count 与 prompt_eval_duration |
查看处理了多少输入及其开销 |
eval_count 与 eval_duration |
比较同一工作负载的输出生成 |
total_duration |
把整个请求的开销与各组件计时放在一起看 |
文档中的时长以纳秒为单位。把时长除以 1,000,000,000 得到秒数。计算输出速度时,用 eval_count 除以 eval_duration / 1,000,000,000,前提是时长大于零。例如,生成 100 个 token 耗时 5,000,000,000 纳秒,也就是 5 秒,速度便是每秒 20 个 token;这不是任何 Mac 或模型的实测结果。
不要用输出 token 数除以总时长,然后把它称作纯生成速度。那样会包含加载和输入处理的时间。还要说明重复的提示是否使用了缓存输入,因为第二次请求更快可能同时反映模型已预热和提示被复用。保留完整响应,而不是只报告最好看的数字。
查看实际加载了什么
在终端中检查当前状态:
ollama ps
Ollama FAQ解释了 PROCESSOR 列。它可以显示 GPU、CPU 或两者共同承担的比例。硬件指南记录了 Apple GPU 上的 Metal 加速。如果你期望本地模型使用 GPU,运行结果比基于 Mac 名称的假设更有用。
还要确认请求发往的是你正在检查的本地服务器。前端可能指向另一台主机或云端模型。在这种情况下,本地 ollama ps 输出并不能描述远程请求。
先减小上下文,再归咎于模型大小
模型文件只是内存需求的一部分。更大的上下文需要额外内存,并发请求会增加工作量。Ollama 的上下文长度文档描述了依赖硬件的默认值和应用的上下文控制。不要假设每个安装都有相同的默认值。
要做受控测试,使用短提示词、单个请求和仍然包含该测试所需信息的较小上下文。如果完整的编码任务之后需要更多上下文,就恢复到能容纳必要信息的大小。如果缩短上下文让模型漏掉必要指令,即使回答更快,也不算优化成功。
只把更小的模型或量化作为单独的对比来尝试。它会同时改变资源使用和回答质量。保留几个有代表性的问题,以便评估更快的选项是否仍然有用。
临时测试一次上下文变更
对于简短的诊断提示,API 接受按请求设置的上下文选项。在前面的请求中,在 options 内与 num_predict 一起加入 "num_ctx":4096,并使用支持该上下文的本地模型。这只是一个测试用的示例大小,不是适用于所有模型或编码任务的推荐设置。
保持模型和提示不变,然后用 ollama ps 检查运行中的模型并比较内存压力。不要在一个很大的对话周围缩小上下文,然后假定答案仍然包含每一条指令。先比较一个能装下的小任务;之后再为实际工作负载测试足够容纳其输入的上下文。
FAQ 和专门的上下文长度页面给出的默认值不一致,所以本指南不依赖某个通用默认值。应用设置、前端或请求级选项也可能影响运行时的值。如果已安装版本在 ollama ps 中报告 CONTEXT,把该值与 PROCESSOR 一起记录,而不是从模型文件大小去推断它。
更低的内存读数不是唯一的成功条件。任务仍须以可接受的答案完成,Mac 的其余部分也必须保持可用。如果更小的上下文丢掉了重要事实,或者变更没有带来可重复的差异,就移除测试选项并恢复之前可用的设置。
生成期间观察整个 Mac
打开活动监视器 › 内存,在生成期间观察压力,而不只是在响应结束后。Apple Silicon 使用共享系统内存,所以其他应用也有影响。模型能放在磁盘上,并不等于运行时有足够内存容纳它和其他任务。
保存工作并关闭一个不必要的重任务,然后重复同一请求。如果内存压力下降,回答也随之变快,就可以继续排查并发任务的影响。内存压力指南介绍了如何解读 Mac 的指标,而不把每个缓存字节都当作浪费。
释放空闲模型占用的内存
首先等待任何使用该模型的请求完成。要释放不再需要的已加载模型,使用 ollama stop 后跟来自 ollama ps 的准确名称:
ollama stop MODEL_NAME
运行命令前替换 MODEL_NAME。这会把模型从内存中卸载。它不会删除已下载的文件,下一次请求可能重新加载模型。因此,在请求之间反复卸载模型可能会让体验变慢。
如果磁盘空间才是实际限制,单独在 AI 模型清理指南中查看已存储的模型。保留本地创建的模型以及任何你无法可靠地再次下载的内容。就性能而言,一次只对比一个变化,并始终使用同一组任务对比。
用服务器日志排查不匹配
如果本地请求仍然很慢,或者处理器分配不符合预期,Ollama 的故障排查指南指出 Mac 服务器日志位于 ~/.ollama/logs/server.log。阅读测试时间附近的片段,查找加载失败、内存分配问题或所选的执行后端。对于手动启动的服务器,相应消息可能出现在它的终端里。
记录 Ollama 版本、确切的模型标签、上下文、处理器分配以及主导计时的阶段。在分享日志片段前,检查其中是否包含私人提示和本地路径。不要仅仅因为某个 GPU 或服务器环境变量出现在旧的优化帖子里就去修改多个变量;日志应先指出某个改动要解决的不匹配。