你本地用 ollama 跑着模型,感觉比刚装的时候慢了,或者想比较两个模型、两种量化档位哪个更快,手上却没有一个能站住脚的数。这篇把「从哪拿到速度数字」讲清楚:有哪些现成的字段可以直接读,什么时候得自己发请求测,以及拿到的 token 速度受哪些因素干扰、什么时候不该信。
你本地用 ollama 跑着模型,感觉比刚装的时候慢了,或者想比较两个模型、两种量化档位哪个更快,手上却没有一个能站住脚的数。这篇只讲一件事:从哪拿到速度数字。
分三层看。第一层是服务自己愿意告诉你的字段,零成本,随手就能读;第二层是自己发请求计时,可控但要多写几行;第三层是把数字放进真实场景里读,知道它什么时候可信、什么时候只是你这一台机器的偶然表现。三层都走一遍,你才知道自己手里的数是哪一种。
先定清楚:你要量的是哪个「速度」
速度不是一个数。请求发出去到第一个 token 吐出来,这段叫首字延迟;第一个 token 之后,每个 token 之间的间隔倒数,叫稳态生成速度。你自己盯着终端打字聊天的体验,主要被前者决定;批量灌数据、跑长摘要,主要被后者决定。
- 首字延迟
- 请求发出到第一个 token 出现的时间,交互式聊天里最影响手感
- 稳态生成速度
- 第一个 token 之后每秒产出多少 token,长输出场景里更关键
- 端到端耗时
- 从发请求到收完最后一个 token,中间夹着加载、排队、网络、渲染
这里有个容易踩的坑:把端到端耗时直接除以输出 token 数,得到的不是生成速度,而是「整条链路平均每个 token 花多久」,加载和排队都被摊进去了。想横向对比两个模型,只要每次用同一套条件测,这个混合指标也能用;想对外报一个绝对值,就得先把变量拆开。
最省事的一档:用服务自带的指标字段
命令行交互模式下,退出当次对话会打印一行统计,里面直接带生成速度和耗时明细。这是最快的随手量法,不用写任何代码,聊完就退出看一眼。
走 HTTP 接口时,响应体里通常带一组计数字段:总耗时、加载耗时、prompt 阶段耗时、生成阶段耗时,以及各自对应的 token 数量。把生成阶段的耗时和生成的 token 数相除,才是真正的生成速度。字段的当前含义和口径,以你本地服务版本为准,站内资料库有对照说明可以核。
- 先发一次预热请求,让模型进显存,再跑第二次取数,否则加载时间会算进第一轮
- 对照时优先看生成阶段的两个字段,别用总耗时除以总 token 数
- 同一段 prompt 连续跑三次,看三个数是否稳定,飘得厉害说明后台有干扰
- 把每次的字段值抄在一个表里,模型名、量化档位、prompt 长度各占一列,之后就不用凭感觉比
要更靠谱的数:自己发请求计时
服务自带的字段够用,但它是单次结果,也不方便固定变量。想认真比一比,就自己发请求,把条件锁死。锁死的意思很具体:同一个 prompt、同一个最大输出长度、同一个温度、同一台机器、同一时间窗口内跑完。
- 固定输入把 prompt 写死在脚本里,不要每次手打。prompt 长度直接决定预处理阶段耗时,一改就没法比。
- 清空对话每次请求都开新会话。第二轮往后的对话会把历史上下文重新喂一遍,越长越慢。
- 连跑多轮同一个配置跑五到十轮,取中位数和上下区间,别拿第一次或最快那次说事。
- 记录环境顺手记下当时显存占用、有没有别的重进程、机器是不是在插电状态,这些是解释波动的依据。
- 换变量再跑换模型或换量化档位,其他条件一律不动,两组数才有可比性。
如果你还想知道网络这一段占了多少,可以先到 /tools/speed-test 量一下本机到服务的延迟基线,再把本地推理的耗时拆出来看。涉及调用量估算时,去 /tools/token-price-calculator 换算 token 规模,这两个数用途不同,别混着用。
同一台机器上,什么会让这个数上下跳
先把结论摆前面:同一台机器上跑同一个模型,速度能差出好几倍,多半不是模型变了,是环境变了。知道哪些因素在动,才不会把环境的锅扣到模型头上。
| 影响因素 | 表现 | 怎么处理 |
|---|---|---|
| 模型大小与量化档位 | 参数量越大越慢,量化越轻越快 | 横向对比时先确认两边同一档量化 |
| 显存是否够用 | 部分层被丢到 CPU 或内存,速度掉一个量级 | 这种情况只能说明配置不够,别怪模型 |
| 上下文长度 | prompt 越长,每次生成都要重处理更长上下文 | 测速前清空对话,用同一个短 prompt |
| 后台进程 | 编辑器、浏览器、另一个模型实例在抢显存 | 测之前关掉,测完再开 |
| 并发请求数 | 多请求同时进来互相抢算力 | 测单请求速度时把并发压到 1 |
还有两个容易被忽略的:一是机器本身的散热和降频,笔记本插电和不插电跑出来的数不是一回事;二是首次加载和模型驻留时间,刚启动和跑了几小时的状态也不一样。写结论时把这些一并写上,别人复现不出来也知道差在哪。
这些情况下,测出来的速度别拿去对外说
测速本身不难,难的是知道这个数在什么范围内成立。下面几种情况,数字只能自己参考,不适合当结论往外抛。
- 拿笔记本上的数去和别人的独显机器比,或者拿量化版去和未量化版比:结论只在同配置、同量化、同 prompt 下有效
- 拿单次请求的结果当稳定表现:本地推理受温度和后台任务影响,波动是常态,多轮取区间比取单点实在
- 拿单请求速度推断生产并发能力:本地单机易用和线上高并发吞吐是两码事,后者要另行评估
- 拿聊天里的手感当基准:渲染、终端刷新、你的打字速度都会混进来,量出来的不是模型速度
速度数字只有在条件写清楚的前提下才有意义,写不清条件的数,不如不报。
想把这些数放进更大的坐标系里看,比如同类模型在中转站上的实际表现和价格口径,可以到 /rankings 看当期排序,再到 /price-watch 核对价格变化。所有具体数字都以页面当时显示的为准,别抄旧文章里的值。
下一步先按上面锁变量的方法跑一组数,再去站内把同类模型的口径对一遍,你就知道手里这台机器跑得算快还是算慢。→常见问题
ollama 有没有一条命令能直接看速度?
命令行交互模式退出时会打印当次统计,里面有生成速度这一项,这是最快的随手量法。想要更干净的数,就走 HTTP 接口取响应体里的计数字段,用生成阶段耗时除以生成 token 数,这就是本次请求的稳态生成速度。首次请求会把模型加载时间算进去,建议先预热一次再取数。
为什么我测出来的速度比别人低一大截?
先查三件事:模型和量化档位是不是同一个、显存够不够(不够会有一部分层落到 CPU,速度断崖式下降)、测的时候有没有别的程序在抢显存。再看上下文长度和对话轮数,长上下文会显著拖慢生成。把这几点对齐之后,同配置机器上的数一般不会差太远,剩下的是驱动和系统差异。
这个速度能用来判断机器够不够用吗?
能判断「体感够不够」,不能直接推「能扛多少并发」。单请求速度只说明一个人用着顺不顺;多人同时用会互相抢资源,实际吞吐要按并发压测另算。如果你是要给团队用,先在单请求速度上定一个你能接受的底线,再做多请求测试看衰减幅度,别拿单请求的数字直接乘人数。