“模型能装进我们的硬件吗?”——这是所有人都会问的第一个问题。原因很简单:这个问题回答起来几乎零成本,能加载就是能加载,不能就是不能。
但吞吐量(throughput)是需要实测的。于是容量这一关过了,感觉决策就已经做完了。事实远非如此。
一个真实的案例:Mac Mini M4 跑 27B 模型
拿一台 Mac Mini M4 举例:24GB 统一内存,内存带宽约 120GB/s。要跑一个 27B 参数的模型,用 IQ4_XS 量化后,磁盘上占 15GB。
容量检查:通过。Metal 的 recommendedMaxWorkingSet 是 17.76GB,模型 15GB,ollama ps 显示 100% GPU 驻留。没有 swap,没有 spillover。按所有“能不能装下”的标准来看,这是一次干净利落的通过。
生成速度呢?5.6 tokens/秒。
这个速度不是一个可用的交互式工作负载。连批处理都勉强。而容量检查对此没有任何提示。
带宽天花板:8 tokens/秒
自回归生成(autoregressive generation)每生成一个 token,就要把整个模型的权重读一遍。所以理论上限是:
上限 ≈ 内存带宽 ÷ 每次操作读取的字节数 = 120 GB/s ÷ 15 GB = 8 tokens/秒
实测 5.6,天花板 8,比值 0.70。
这个比值就是全部结论。当实测吞吐量已经是算术上限的很大一部分时,说明你被带宽卡住了。这时候你能确定一件事:瓶颈不是你的配置,不是内存压力,不是温度降频,而是字节搬运的速度。
经验法则:比值 ≥ 0.5 就是带宽受限
我现在用的经验法则是:比值 ≥ 0.5 → 带宽受限,此时靠缩小模型体积来提速基本是死路。
容量紧张时,本能反应是缩小模型。更低量化、更小批次、更重压缩。这是条件反射,但在带宽受限的情况下,这几乎没用。
我当时在考虑用 Q3_K_M 量化,体积 13.8GB。做同样的除法:
120 ÷ 13.8 = 8.7 tokens/秒(从 8 提升到 8.7)
吞吐量提升不到 9%。代价是输出质量实实在在的下降——量化误差随体积缩小的速度,远没有带宽提升来得快。在这个区间里,你付出的比得到的多,每次都是。
我什么都没下载就毙掉了这个方案。这就是这条规则带来的节省:用算术拒绝,而不是花一下午去 benchmark 一个根本不可能赢的模型。
容量和吞吐量是两套资源
更深层的原因是,容量和吞吐量由不同的资源决定。容量是内存的字节数。吞吐量是总线上每秒流过的字节数。拉动容量这个杠杆,改变的是容量数字。它碰触吞吐量上限的方式,仅仅是通过“更小的模型需要流式传输的字节更少”这个附带事实——一个微弱的、严格线性的耦合,而你为它付出的代价是非线性的。
这就是为什么这笔算术值得做。一旦你确定是带宽问题,同一个模型在不同硬件上的表现,就是一次除法的事:
结论会随硬件翻转,而不是随模型大小翻转。“这个模型太慢”从来就不是事实——“这个模型在 120GB/s 的带宽上太慢”才是。这两个判断会导向完全不同的购买决策,而其中只有一个是对的。
先算带宽,再谈优化
下次再遇到“模型装得下但跑不动”的情况,先别急着换量化方案。拿内存带宽除以模型体积,看看天花板在哪,再对比实测速度。如果比值已经超过 0.5,省下下载模型的时间,直接考虑换硬件或者换模型。这笔算术,比一下午的调参值钱得多。
热门跟贴