Ollama 运行 DeepSeek 很慢,先区分模型加载、输入处理和逐 token 生成三个环节。第一次等待很久可能主要在加载;连续请求都慢则需要检查计算设备、上下文和资源。用同一条请求记录 API 计时字段,比凭感觉增加参数更容易找到下一步。
先确认模型能完成回答
适用前提是模型已经下载,能够返回完整回答;连接失败、下载失败或加载报错应先按对应错误处理。这里以 deepseek-r1:7b 为例,记录 Ollama 版本、模型标签、系统和显卡驱动,暂时关闭其他模型任务。

按 Generate API 文档,load_duration、total_duration 和 eval_duration 等计时使用纳秒,输出 token 数在 eval_count。生成速度计算为 eval_count / (eval_duration / 1e9),不能拿总耗时替代生成耗时而不注明口径。
用相同请求连续测三轮
保存为 benchmark.py,用 Python 3.10 或更新版本执行 python benchmark.py。示例固定问题、上下文设置和输出上限,保留模型 10 分钟,便于比较连续请求:
"""Article example: same non-streaming request three times."""
import json
from urllib.request import Request, urlopen
url = 'http://127.0.0.1:11434/api/generate'
payload = {'model': 'deepseek-r1:7b',
'prompt': '只回答一个数字:17 加 25 等于多少?',
'stream': False, 'keep_alive': '10m',
'options': {'num_ctx': 2048, 'num_predict': 128}}
for round_id in range(1, 4):
req = Request(url, data=json.dumps(payload).encode('utf-8'),
headers={'Content-Type': 'application/json'}, method='POST')
with urlopen(req, timeout=300) as response:
data = json.load(response)
if data.get('done') is not True:
raise RuntimeError('请求未完成,不纳入比较')
if data.get('done_reason') == 'length' or not data.get('response', '').strip():
raise RuntimeError('回答截断或最终正文为空,请调整输出上限后重测')
fields = ('load_duration', 'total_duration', 'prompt_eval_duration',
'eval_duration', 'eval_count')
if any(key not in data for key in fields):
raise RuntimeError('计时字段缺失,不能将缺失值当成零耗时')
seconds = data.get('eval_duration', 0) / 1e9
speed = data.get('eval_count', 0) / seconds if seconds else None
print({'round': round_id, 'model': data.get('model'),
'load_s': data.get('load_duration', 0) / 1e9,
'total_s': data.get('total_duration', 0) / 1e9,
'prompt_eval_s': data['prompt_eval_duration'] / 1e9,
'prompt_tokens': data.get('prompt_eval_count'),
'output_tokens': data.get('eval_count'), 'tokens_per_s': speed,
'answer': data.get('response')})
这是诊断脚本,没有预填真实结果。每轮核对答案;若因输出上限产生截断,脚本会停止。思考模型可能把输出预算消耗在思考上,最终正文为空时应增加合理输出上限后整组重测,不能把空答案的高速度计作优化成功。
第一轮不一定是冷加载:如果模型本来就在内存中,它也可能是热请求。确需比较冷加载时,确认没有其他调用者,再用 ollama stop deepseek-r1:7b 卸载运行中的模型,之后重新运行这组三轮;不要在别人正在使用的共享服务上执行。
根据实际字段判断瓶颈
| 观察 | 更可能的环节 | 下一步 |
|---|---|---|
| 首轮 load_s 较大,后续明显下降 | 加载模型或冷启动 | 确认是否频繁卸载、切模型,避免每次请求都把 keep_alive 设为 0 |
| 各轮加载很小,但生成速度持续较低 | 解码计算或资源限制 | 查看实际 CPU/GPU 分配、后台负载、模型规模和量化 |
| 短问题正常,长输入明显变慢 | 输入处理、上下文或内存压力 | 固定同样输出上限,分别记录输入 token 数和输入处理耗时 |
| 单请求正常,多个请求等待或 503 | 排队和资源容量 | 减少客户端并发并检查服务日志,而不是只扩大队列 |
冷、热请求的提示缓存和模型随机输出也会影响比较。计时字段缺失时脚本停止,不把缺失值当成零;token 生成速度也不等于可见文字的字数速度,思考模型还可能生成思考内容。尽量重复固定任务,记录输出长度和是否截断;三轮结果是故障定位线索,不是具有统计意义的性能排行榜。
看实际运行设备,不只看电脑有显卡
ollama ps
官方 FAQ 说明 PROCESSOR 列可显示 100% CPU、100% GPU 或混合分配。List running models API 也提供运行模型和 size_vram 等信息。运行时没有模型时列表可能为空,先完成一轮生成再看。
如果实际在 CPU 上,先按当前系统的 GPU 文档核对设备和驱动,不要通过随意设置一个变量就宣称 GPU 已启用。如果 CPU/GPU 混合,结合系统内存、显存和日志判断;显卡利用率短暂低不能独立证明配置错误。
一次只改一个变量,再核对答案
- 先保持同一模型与问题,减少无关后台任务和并发,复测三轮。
- 若内存压力明显,使用与任务相符的较短上下文,再复测;不能裁掉任务必要资料只追求速度。
- 若仍不足,再比较可核实的更小模型或量化版本。更换后同时用自己的固定问题集核对答案质量。
- 记录改动、计时和答案,能够解释改善来自哪一项,再决定是否保留。
keep_alive 可以减少重复冷加载,但模型常驻会占内存;并发增加也可能放大上下文内存需求。它们不是免费的提速开关。仍无法定位时,提供脱敏后的版本、模型、设备分配、三轮记录和对应时间日志,不能只提交一句“很卡”。
本文没有在你的硬件上测量速度,未给出任何真实吞吐量或提速倍数。命令和字段按 2026 年 10 月 1 日的官方资料核对;脚本输出须由你运行后记录。
Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/30138.html