本文由 莫潇羽@源码七号站(www.fuyuan7.com)撰写,转载请注明出处。
快速摘要
这两年开源大模型卷得很凶,从 Llama、Qwen 到 Gemma,本地部署的门槛肉眼可见地往下掉。但门槛低不等于不踩坑——HuggingFace 上挂着上百万个开源权重,参数从 1B 到 100B+ 都有,光是判断"我这张卡能跑哪一个"就够人头大。等下载完一二十 GB 的权重,发现一句话要等半分钟才吐完,那种试错成本谁踩过谁知道。本文从一线视角讲清楚一件事:与其拍脑袋挑模型,不如让一个叫 whichllm 的开源命令行工具帮你把硬件、显存、量化、基准分数全部算明白,一条命令直接给出"在你这台机器上又快又好"的推荐列表,必要时还能直接下载并开聊。
往下读你会看到:本地部署到底卡在哪一步、whichllm 是怎么把"能跑"和"跑得好"分开判断的、它内部那套打分逻辑长什么样、显存到底被什么吃掉了、Q4_K_M / Q5_K_M 这些后缀该怎么选,以及在 24GB 显卡、Apple Silicon、纯 CPU 三种典型场景下的真实选型思路。想看完整拆解,往下翻。
一、本地跑大模型这件事,现在到底卷到哪一步了
聊工具之前,我想先掰扯几句"为什么越来越多人愿意把模型搬到自己机器上跑"。这件事不像一年前那么小众了,我身边做内容、做产品、做研究的朋友,凡是稍微对 AI 上心一点的,都至少尝试过一次本地部署。
1.1 开源权重已经卷到"够用"这条线之上
最直观的变化是模型质量。两年前你拿一个 7B 的开源模型出来,回答稍微复杂一点的问题就开始胡言乱语,对话两轮就跑题。今天再看 Qwen、Gemma、Llama 这几条主线的新版本,参数规模没怎么涨,但在常用的对话、代码、数学这些任务上,跟一年前的闭源大模型已经能掰一掰手腕了。
这就解锁了一个之前不太成立的场景——对很多日常任务来说,跑一个本地模型其实就够用了。写写文档大纲、整理资料、改改代码、做点 RAG 检索的胶水层,根本不需要顶配旗舰模型。一台游戏本配一张消费级显卡,跑 7B 到 14B 的模型完全没压力。
1.2 闭源 API 的"Token 账单"开始变得肉疼
另一个推力是钱。早期玩 API 的时候,大家手里都是几美元、几十美元的额度,怎么用都用不完。等真把它接进自己的工具链里,每天几十万 Token 起步,账单就开始唰唰往上窜。
我自己有个习惯:手头一旦有"能批量跑、能离线跑、对延迟不敏感"的活,比如批量摘要、批量翻译、批量打标签,就尽量挪到本地。这部分活就算每次回答慢一点,也比每天烧十几二十美元 Token 划算。莫潇羽@源码七号站之前算过一笔账,纯纯把这类批量活迁到本地,一台二手游戏本的电费摊到两年里,比 API 便宜不止一个数量级。
1.3 数据不出门是个硬需求
钱之外还有数据。涉及到客户资料、合同、内部知识库这些东西,公司层面不允许把数据塞进第三方 API,这件事在国内特别普遍。本地部署是绕开这层风险最直接的方案,模型权重、对话内容、向量索引全部都在自己机器上,谁也别想顺走。
这一波下来,本地大模型的需求人群也从原本的"研究者 + 极客"扩散到了更广的开发者、内容创作者、企业 IT 团队。
1.4 推理工具链也跟着成熟了
光有模型还不够,得有能把模型跑起来的引擎。这两年 llama.cpp 把 CPU 和各种异构硬件都吃下去了,Ollama 把模型管理打包成了"一行命令搞定",LM Studio 把可视化界面也做出来了,HuggingFace Transformers 在 GPU 这一侧继续扩张,AWQ、GPTQ、GGUF 这些量化方案各有各的地盘。
工具链一全,原本只能在 Linux + CUDA 这条狭路上玩的游戏,现在 Windows、macOS、纯 CPU、Apple Silicon、AMD 显卡,几乎都有自己的路子可走。这就把本地部署的硬件门槛从"得有一张 A100"压到了"有一台还算新的笔记本就行"。
1.5 但热闹归热闹,新手第一步就容易劝退
听起来一片大好,对吧?等真上手就会发现,事情卡在了一个意想不到的地方——"我该选哪个模型"。
HuggingFace 上挂着上百万个模型仓库,光是 Qwen 这一个系列就有 1.5B、3B、7B、14B、32B、72B 各种尺寸,再叠上 Instruct / 基座 / 数学专精 / 代码专精,再叠上 GGUF 的十几种量化档位,光是排列组合就能让人当场放弃。
新人最常见的两种死法:第一种,看参数大就选,结果下载完发现塞不进显存;第二种,盲选一个小的,结果跑起来又笨又慢,体验极差,再也不想碰本地部署。
我下面要讲的这个工具,就是冲着这个痛点来的。
二、本地部署的真正难点,从来都不是"能不能跑"
很多人第一次部署,第一反应是去算"我的显存够不够"。这个直觉不算错,但只对了一半——"能塞进去"和"跑得舒服"是两件完全不同的事。我在这一章想把这件事讲透,因为后面 whichllm 的设计逻辑就建立在这之上。
2.1 "能跑"只是入场券
先说显存这件事。一个常见误区是直接把模型文件大小拿来对标显卡显存。比如下载下来一个 14GB 的 GGUF 文件,看到自己显卡 16GB,就以为稳了——结果一加载,OOM。
真实情况是,显存里塞的东西远不止权重。除了模型本身,还有 KV 缓存(保存历史 token 的注意力键值对)、激活值(前向计算的中间张量),加上推理引擎自身的开销,零零碎碎加起来很容易再吃掉几个 GB。
更隐蔽的是操作系统和显示器也在偷偷占显存。你以为自己有 24GB 显存可用,实际上扣掉系统、扣掉桌面渲染、扣掉浏览器,能给模型的可能只有 17、18GB 左右。这部分等到下面"显存怎么花掉的"那一章会展开讲,这里先记住一句话:模型大小 ≠ 显存占用,能塞进去也不代表能舒服跑。
2.2 速度才是真正决定"用不用得下去"的指标
第二件事,是吐字速度。
我自己定义过一个非常粗糙的"可用阈值":对话场景下吐字速度低于 10 tok/s 就开始难受,低于 5 tok/s 基本可以扔了。批量任务可以慢一点,但慢到一定程度也会变成"挂机等结果",体验跟卡死也没什么区别。
吐字速度跟什么有关?三件事:
- 显存带宽:每秒能往计算单元里灌多少权重,本地推理基本是带宽瓶颈。
- 模型大小(受量化方式影响):权重越大、每生成一个 token 要搬运的数据越多。
- 上下文长度:上下文一长,KV 缓存也涨,每一步注意力计算都要扫一遍。
也就是说,同一张卡跑同一个模型,换个量化方式速度可能差三倍;同一个模型跑在不同带宽的卡上,速度可能差十倍。光看参数量,根本没法估计真实体验。
2.3 "新模型"比"大模型"更香
第三件容易被忽略的事,是模型代际差。
早两年大家有个朴素印象——参数越大越聪明。这件事现在已经不成立了。这一年开源社区做了大量工作,新一代 10B 级别的模型,在常用对话和代码任务上,吊打两年前 30B 级别的老模型并不少见。
举个具体例子。一张 24GB 显存的 RTX 4090,理论上塞得下一个 32B 老模型的 Q4 量化版。但同样硬件下,如果有一个 27B 的新一代模型,它在基准测试上的得分更高、思考能力更强、训练数据也更新,那你应该选哪一个?答案显然是后者——更小、跑得更快,质量还更好。
这就引出一个核心结论:选模型不能只看参数量,必须把"模型新不新"、"在真实基准上表现如何"也一起考虑进来。否则你选的可能是一个"看起来很大、实际上很傻"的模型。
2.4 量化和格式:选对一档就回血一档
第四件事,是量化格式。
同一个 7B 模型,FP16 全精度大概要 14GB 显存,Q8 量化掉一半到 7GB 左右,Q4 再砍一半到 4GB 出头。从 14GB 压到 4GB,听起来很美好,但天下没有免费的午餐——量化压得越狠,模型回答质量就掉得越多。
主流的量化挡位里,Q4_K_M 被公认是"性价比黄金点",压缩比够高、质量损失能接受,是目前本地部署最常见的默认选择。Q5_K_M 稍微大一点、质量更接近原版,适合显存还有余量的人。Q8_0 基本接近无损,但已经压不出多少显存了,更多是给"对答案精度有强需求"的场景准备。
除了 GGUF 这一套量化体系,NVIDIA 卡上还能选 AWQ、GPTQ 这种走 transformers 框架的量化方案。Apple 芯片和纯 CPU 机器,目前最稳的还是只走 GGUF——这也是后面 whichllm 在这类硬件上只推荐 GGUF 的原因。
2.5 一个真实的"试错成本"故事
把上面这些堆在一起,新手第一次部署常常变成这样的流程:
打开 HuggingFace -> 看到某个热门模型 -> 下载二十几 GB 权重 -> 等半小时 -> 加载报 OOM -> 删了换一个量化 -> 再下十几 GB -> 加载成功但每秒 2 个 token -> 删了换一个更小的 -> 速度上来了但答案明显变笨 -> 再换......
我自己刚开始那阵子,这一套循环至少跑过四五遍,每次都得"下载-部署-测试-卸载"。试错成本主要不是时间,而是带宽和心情。十几 GB 的权重在国内下一次至少半小时起步,一晚上能折腾完两三个就算高效。等真的找到一个"又跑得动又跑得好"的组合,已经凌晨两点了。
也是因为这个,社区里一直有人在试图把"选模型"这件事自动化。早期的方案大多是写死的对照表——某某显卡能跑某某模型,但这种表既不更新,也不考虑量化和速度,参考价值很有限。
后来我才看到 whichllm 这种把硬件检测、模型库、基准评分捏到一起的工具,整个体验确实清爽了一个量级。下一章我把这个工具拆开讲。
三、whichllm 是什么:一句话讲清楚它解决了什么
whichllm 是一个开源的命令行小工具,作者是 GitHub 用户 Andyyyy64,项目挂在 github.com/Andyyyy64/whichllm ,MIT 协议,用 Python 写的,整个仓库不算特别大但麻雀虽小五脏俱全。
一句话概括它做的事:自动识别你机器的硬件配置,然后从 HuggingFace 上拉一份带基准评分的模型列表,挑出"既能在你这台机器上跑得动、又跑得最快最聪明"的那批模型,按打分高低排好序给你看。
3.1 它跟老式的"显存对照表"不一样在哪
社区里之前不是没有类似的工具。最早的几款都是 TUI 风格,进去之后要在终端里翻菜单、记快捷键,自己一项一项点开模型查参数。问题也很明显:
- 数据是写死的,新模型出来之后还要等作者更新,常年滞后;
- 只算"能不能塞进显存",不管你跑起来到底是 30 tok/s 还是 3 tok/s;
- 不考虑模型质量差异,参数量差不多就被当成"差不多的模型";
- 基本是为单机互动设计的,没法被脚本调用、没法接到自动化流程里。
whichllm 的设计思路反过来——直接对接 HuggingFace API 拉模型清单、整合 Chatbot Arena ELO 和 Open LLM Leaderboard 的基准分数、配上自己一套显存/速度估算,一条命令出结果,要 JSON 给 JSON,要表格给表格,特别适合塞进个人工作流里。
3.2 一组例子,直观感受一下
最能说明问题的是它给出的推荐顺序。前面提到过那个例子,我把官方 README 里的截图意译一下,体感会非常清楚。假设你模拟一张 24GB 的 RTX 4090:
|
排名 |
模型 |
参数量 |
量化 |
综合分 |
速度估计 |
|
#1 |
Qwen3.6-27B |
27.8B |
Q5_K_M |
92.8 |
27 tok/s |
|
#2 |
Qwen3-32B |
32.0B |
Q4_K_M |
83.0 |
31 tok/s |
|
#3 |
Qwen3-30B-A3B (MoE) |
30.0B |
Q5_K_M |
82.7 |
102 tok/s |
注意看这张表。32B 那个塞得进显存、速度还更快,但综合分只有 83 分,被排到了第 2;27B 那个稍微小一点、速度稍微慢一点,但综合分高到 92.8,因为它是更新一代的模型,在真实基准上更强,所以被推荐到第 1。第 3 名是个 MoE(混合专家)架构,激活参数才 3B,吐字速度直接飙到 102 tok/s,适合优先要响应速度的场景。
这就是 whichllm 跟"傻瓜对照表"最大的差别:它不是告诉你"哪些能跑",而是告诉你"哪个跑起来综合体验最好"。
3.3 支持的硬件覆盖面
底层硬件检测这一块,whichllm 做得比较扎实:
- NVIDIA 显卡:通过
nvidia-ml-py拉显存、型号、计算能力,这条路最成熟; - AMD 显卡:在 Linux 上能用 ROCm 工具链识别,Windows 上要靠系统接口补全,精度差一些;
- Apple Silicon(M1/M2/M3 系列):通过 Metal 接口识别统一内存大小;
- 纯 CPU 模式:识别核心数、AVX 支持、内存大小,给出 CPU-only 的推荐;
- GPU 模拟:用
--gpu "型号名"假装你有某张卡,特别适合在买卡之前做选型预演。
我自己在三台机器上分别试过——一台 RTX 4060 的 Windows 游戏本、一台 M2 的 MacBook Air、一台老旧的纯 CPU 台式机,三种环境识别都没出错,推荐列表也都给得合理。
3.4 它能直接帮你把模型跑起来
更舒服的一点是,whichllm 不只是"推荐",还能直接接住下一步——whichllm run 一条命令,它会自动挑一个最匹配的模型、自动选量化档位、自动下载、自动起一个隔离的 Python 环境(通过 uv 工具),最后直接进入对话界面。
你完全不用关心:装什么推理库(GGUF 走 llama-cpp-python,AWQ/GPTQ 走 transformers + auto-awq/auto-gptq,FP16 直接 transformers)、装哪个版本、显存怎么分配、上下文怎么设置——这些它都帮你算好。从"装好这个工具"到"开始对话",差不多就两条命令的距离。
对于纯 CPU 用户,也有一个开关:--cpu-only。它会自动把推荐范围收窄到能在 CPU 上跑得动的小尺寸 GGUF,避免你拿一个 14B 模型去硬怼 CPU。
3.5 它有几个值得说一说的"加分项"
最后讲三个我特别喜欢的小设计:
- 基准分数带置信度标记。一个模型如果有直接的基准评分就标
direct,没有就退到variant(变体匹配)、base_model(基座模型推断)、line_interp(同家族线性插值),每一档置信度不同,最终打分会做相应的折扣。这点比"一刀切给个分"严谨太多。 - 数据有 TTL 缓存。模型清单缓存 6 小时,基准分数缓存 24 小时,文件放在
~/.cache/whichllm/,重复跑命令不会反复打 HuggingFace API,体验顺滑。 - 可以走 JSON 输出。命令后面加个
--json,整个推荐结果以结构化 JSON 吐出,配合jq直接管道给 Ollama、给脚本、给自动化工作流,怎么都好接。
我自己在 .zshrc 里加了一行别名 alias bestllm='whichllm --top 1 --json | jq -r ".models[0].model_id"',需要换模型的时候一行命令就能拿到最优 ID,剩下扔给 Ollama 跑就完事。莫潇羽@源码七号站个人工作流里现在这套用得相当频繁。
四、五分钟上手:从装好到拿到第一份推荐
讲这么多原理,不如直接动手。整个工具的安装和首次使用,体验上跟"装一个 pip 包,敲一条命令"差不多。我在这一章把流程完整走一遍。
4.1 装它
官方提供了三种安装方式,挑一个顺手的就行。
方式一:pipx(官方推荐)
pipx install whichllm
pipx 是专门管"命令行 Python 工具"的小工具,它会把 whichllm 装进一个隔离环境,不污染你系统 Python。如果还没装 pipx,先 pip install pipx && pipx ensurepath 一下。
方式二:Homebrew(macOS / Linux)
brew tap Andyyyy64/whichllm
brew install whichllm
mac 上这条路最丝滑,跟装其他 brew 包没什么区别。
方式三:直接 pip
pip install whichllm
简单粗暴。我自己一开始就是这么装的,唯一的小坑是要确保 Python 版本 ≥ 3.11,工具有这条硬性要求。
如果你想跟最新版本(包括尚未发到 PyPI 的小修小补),也可以用 uv:
uv tool install whichllm
uv tool upgrade whichllm # 后续升级
或者临时跑一次不留存:uvx whichllm@latest。
4.2 第一条命令:跑出推荐列表
装好之后,终端里直接敲:
whichllm
这条命令什么参数都不带,就是默认行为——自动识别硬件,给当前机器算一份推荐。第一次跑会稍微慢一点,因为它要去 HuggingFace 拉模型清单、拉基准数据,再做一遍打分排序。后面几次有缓存就快了。
输出大致是这么一张表:
Hardware detected
─────────────────
GPU : NVIDIA GeForce RTX 4060 (8 GB)
CPU : Intel(R) Core(TM) i7-13700H
RAM : 32 GB
Backend : llama-cpp-python (GGUF) / transformers (AWQ, GPTQ)
Top models for your hardware
────────────────────────────
# Model Params Quant Score Speed
1 Qwen/Qwen3-7B-Instruct-GGUF 7.6B Q5_K_M 87.4 42 t/s
2 google/gemma-3-7b-it-GGUF 7.0B Q5_K_M 84.1 45 t/s
3 meta-llama/Llama-3.1-8B-... 8.0B Q4_K_M 81.6 51 t/s
...
表格的每一列含义:
- Model:HuggingFace 上的仓库路径,可以直接复制去 HF 上看;
- Params:参数量,单位 B(十亿);
- Quant:推荐的量化档位,工具会基于你的显存挑一个最合适的;
- Score:综合评分(0–100),越高越值得选;
- Speed:估算的吐字速度,单位 token/s,是按显存带宽和参数量推算的,可能跟实测有出入,但用来横向对比足够。
如果分数后面出现 ~ 表示"没有直接基准,是从同家族其他模型推断的",出现 ? 表示"完全没有基准数据"。这两种结果可信度会低一点,看到的时候心里有个数就行。
4.3 几个高频选项
刚上手最常用的几个开关,列出来备查:
# 显示更多候选模型
whichllm --top 20
# 指定量化档位(只看 Q4_K_M)
whichllm --quant Q4_K_M
# 设定一个速度下限(低于 30 tok/s 的不显示)
whichllm --min-speed 30
# 改 KV 缓存上下文长度(默认 4096)
whichllm --context-length 32768
# 切到任务侧重:编程 / 视觉 / 数学
whichllm --profile coding
whichllm --profile vision
whichllm --profile math
# 只看 GPU 完整放得下的模型,不要部分卸载方案
whichllm --direct
# 强制刷新缓存,重新拉数据
whichllm --refresh
# 只想看硬件信息,不要推荐
whichllm hardware
# 输出 JSON,方便脚本接
whichllm --json
--profile 这个开关我用得比较多。默认 general 是综合分,但如果你主要拿来写代码,切到 coding 之后排序逻辑会偏向 HumanEval、MBPP 这类编程基准;切到 vision 会把多模态模型(image-text-to-text)也加进来。任务不同,最优模型就完全不同。
4.4 第一次跑可能踩到的小坑
按经验列几条:
- 首次拉数据慢:默认会去 HuggingFace 拉模型清单,国内网络不太通的话,建议先准备好
HF_ENDPOINT=https://hf-mirror.com这类镜像环境变量。 - AMD 显卡在 Windows 上识别精度有限:作者在文档里也明说了,AMD 这一支在 Windows 上靠的是系统接口补全信息,没 Linux ROCm 那么准。如果你是 AMD + Windows 用户,看到识别结果有偏差不要慌,可以用
--gpu手动指定一次。 - 速度估算是理论值:底层公式是"权重大小 / 显存带宽"加一些修正,跟你实测可能差 10%~30%。它的核心价值是横向对比,不是绝对预测,所以排名比数字本身更值得参考。
走完上面这几步,基本就算入门了。下一章我们把 whichllm 那几条"非默认命令"拆开讲——这些才是它真正区别于"对照表式工具"的地方。
五、四条核心命令拆开讲:run、plan、--gpu、snippet
whichllm 这个默认入口已经很能打了,但它真正让我觉得"做这个工具的人懂行"的部分,是下面这四条扩展命令。每一条都对应一个本地部署中常见的痛点。
5.1 whichllm run:从零到对话,两步走
我们先回到一个最基础的需求:我刚装好这工具,能不能不让我自己再去研究 llama.cpp 怎么编译、transformers 怎么加载,直接进入对话? 答案是 whichllm run。
最简单的玩法:
whichllm run
不带任何参数,它会先跑一遍打分流程,挑出 Top 1 那个模型,然后自动做下面这一串事:
flowchart LR
A[whichllm run] --> B[硬件检测]
B --> C[拉模型/基准数据]
C --> D[打分排序]
D --> E[挑 Top 1 模型]
E --> F[创建隔离环境 uv]
F --> G[安装推理依赖]
G --> H[下载权重]
H --> I[进入交互聊天]
这里有一个细节我特别想夸:整个推理环境是用 uv run --no-project 起的临时隔离环境,不会污染你当前的 Python。GGUF 模型走 llama-cpp-python,AWQ/GPTQ 走 transformers + autoawq/auto-gptq,FP16/BF16 走 transformers,每条路径所需的库都装在对应的隔离环境里,互不打架。
也可以指定模型名:
whichllm run "qwen 2.5 1.5b gguf"
注意它的参数支持"模糊匹配"——你不需要写完整的 HuggingFace 仓库路径,给一个能唯一定位的关键词就行。"qwen 2.5 1.5b gguf" 这种自然语言式的输入,背后会被解析成具体的 repo+filename。
如果你是纯 CPU 用户,加一个 --cpu-only:
whichllm run "phi 3 mini gguf" --cpu-only
它会强制走 CPU 推理路径,省得自动选模型时挑了个塞不进 CPU 内存的。
第一次 whichllm run 完整跑通的那一刻,会有种"啊,原来本地部署可以这么省事"的错觉——但其实只是因为之前那些零零碎碎的步骤都被一条命令吃下去了。
5.2 whichllm plan:你想要的模型,需要什么样的硬件?
run 解决的是"模型选完之后怎么跑起来",plan 解决的是反向问题:"我心里有个看中的模型,我得有什么样的显卡才跑得动?"
whichllm plan "llama 3 70b"
执行之后它会告诉你:
- 这个模型不同量化档位下,最小显存需求是多少;
- 哪些消费级显卡(4090 / 5090 / 4080S 等)能完整放下;
- 哪些只能走"部分卸载"(部分层放显存、部分层放内存);
- 在每种方案下,预估速度大概是多少 tok/s。
你也可以指定量化和上下文:
whichllm plan "Qwen2.5-72B" --quant Q8_0
whichllm plan "mistral 7b" --context-length 32768
这条命令最适合的场景,是你已经看上某个特定模型,想知道现在的硬件够不够 / 要升级到什么程度。我自己买卡之前都会先用这条命令算一遍,避免买回来才发现塞不下。
5.3 whichllm --gpu:买卡前的"沙盘推演"
跟 plan 思路相反,--gpu 是另一个方向上的预演:"我打算买这张卡,但还没买,先看看这张卡能跑什么。"
whichllm --gpu "RTX 4090"
whichllm --gpu "RTX 5090"
whichllm --gpu "H100"
工具内部维护了一份主流 GPU 的型号库(显存大小、显存带宽、计算能力),输入卡名就能合成一个"假装存在"的硬件,给出推荐结果。
还有一条 upgrade 子命令更直白:
whichllm upgrade "RTX 4090" "RTX 5090" "H100"
直接横向对比三张卡:同一份模型库,每张卡分别能跑哪些 Top 模型、速度差多少、综合分高在哪。这等于把"买卡纠结症"压成了一份对比表。
我个人觉得这是 whichllm 的几个杀手锏之一。对于多数普通玩家来说,买显卡是一个决策成本很高的动作——一张 4090 的预算够下一两条小狗了。能在花钱之前先做几次推演,意义比想象中大。
5.4 whichllm snippet:拿到一段可以直接复制粘贴的 Python
最后一条命令,是给爱写代码的人的:
whichllm snippet "qwen 7b"
它会打印出一段开箱即用的 Python 代码,类似下面这样:
from llama_cpp import Llama
llm = Llama.from_pretrained(
repo_id="Qwen/Qwen2.5-7B-Instruct-GGUF",
filename="qwen2.5-7b-instruct-q4_k_m.gguf",
n_ctx=4096,
n_gpu_layers=-1,
verbose=False,
)
output = llm.create_chat_completion(
messages=[{"role": "user", "content": "Hello!"}],
)
print(output["choices"][0]["message"]["content"])
n_gpu_layers=-1 意味着把所有层都丢到 GPU 上跑,n_ctx=4096 是默认上下文长度。如果你想换量化,再加个 --quant:
whichllm snippet "llama 3 8b gguf" --quant Q5_K_M
它会自动把对应的 GGUF 文件名换掉。这对"想把本地模型嵌进自己的小工具/脚本"的人来说太友好了——几乎不用读文档,复制粘贴就能跑。这一条不起眼,但实操体验上加分极多。
5.5 跟 Ollama 串起来用,效率再翻倍
如果你已经在用 Ollama 管模型,whichllm 跟它配合也很丝滑。官方给的两个小示例特别能说明问题:
# 找当前硬件最优模型,直接交给 Ollama 跑
whichllm --top 1 --json | jq -r '.models[0].model_id' | xargs ollama run
# 找当前硬件最优"编程模型",直接 Ollama 跑
whichllm --profile coding --top 1 --json | jq -r '.models[0].model_id' | xargs ollama run
第一条管"日常对话最好的模型",第二条管"写代码最好的模型"。配合 shell 别名再优化一下:
# 加到 .bashrc / .zshrc
alias bestllm='whichllm --top 1 --json | jq -r ".models[0].model_id"'
# 用法
ollama run $(bestllm)
ollama run $(bestllm --profile coding)
这个工作流我用了两个月,模型更新一波我就重新跑一次 whichllm,Ollama 那边自动顺着拉新的最优模型,等于把"模型选型"和"模型运行"这两件事都自动化掉了。从此再没出现过"哎,我现在装的这个模型还是不是最优的"这种纠结。
六、它的"打分逻辑"到底靠不靠谱
工具好不好用,最终还是看它推荐出来的东西对不对。这一章把 whichllm 的内部打分逻辑拆开看一看,重点是搞清楚两件事:它是怎么算分的?这套分数是不是值得信?
6.1 打分的五个维度
whichllm 的总分是 0–100 分制,由五个维度加权得来:
|
维度 |
分值范围 |
含义 |
|
模型规模 |
0 – 40 |
参数越大,潜在质量越好 |
|
基准评分 |
0 – 10 |
Arena ELO / Open LLM Leaderboard |
|
推理速度 |
0 – 20 |
tok/s 越高,实用性越强 |
|
来源可信度 |
-5 – +5 |
官方仓库加分,二次打包扣分 |
|
流行度 |
0 – 3 |
下载量、点赞数做加权小项 |
注意这套权重的分布——模型规模虽然占比最高(40 分),但基准评分和速度合起来也有 30 分,足够把"参数大但跑得慢"的模型从榜首拽下来。再加上来源可信度的正负调整,整套打分逻辑刻意压制了"傻大粗"的偏向。
我用一个具象的例子讲一下加权后的效果。假设比较两个模型:
- 模型 A:32B、Q4 量化、速度 31 tok/s、Arena ELO 1200、来自二次打包仓库;
- 模型 B:27B(新一代)、Q5 量化、速度 27 tok/s、Arena ELO 1300、官方仓库。
A 在"规模分"上略占优,B 在"基准分"、"来源可信度"上反超。最后 B 的综合分会显著高于 A——模型够新、官方出品、基准上更强,这些都比"多 5B 参数"重要。这跟开篇官方截图里 27B 反超 32B 的故事完全吻合。
6.2 基准数据从哪里来
打分里最关键的一块是"基准评分"。whichllm 不是自己跑 eval,而是把社区现成的、可信度比较高的几份榜单拿过来融合:
- Chatbot Arena ELO:人类盲评的对战 ELO 分数,反映"真人觉得这个模型回答好不好",可信度最高,作为优先源;
- Open LLM Leaderboard:自动化 benchmark 套件的综合分;
- LiveBench / Aider / Artificial Analysis:编程、数学、推理这些垂直榜单;
- 多模态/视觉 benchmark:用
--profile vision时才会加权进来。
这种"多源融合"的好处是抗噪——单一榜单容易被刷或被偏向,几个一起看就稳得多。
6.3 置信度分级:没基准数据怎么办
这是 whichllm 设计里我觉得最聪明的一块。HuggingFace 上模型数量太多了,相当一部分模型并没有对应的公开基准分数(比如刚发布几天的新模型、小众微调版本)。如果"没有数据就给 0 分",那这些模型在排行榜上永远不见天日;如果"瞎估一个分",又会破坏整个排序的可信度。
whichllm 的做法是给每条基准分数打一个"置信度等级":
|
等级 |
含义 |
折扣力度 |
|
|
这个模型 ID 在榜单上直接有分 |
不打折 |
|
|
同名不同后缀(如 |
轻度打折 |
|
|
模型卡 cardData 里指明的基座模型有分 |
中度打折 |
|
|
同家族内按参数量做线性插值 |
重度打折 |
最后排序时,分数本身和置信度一起决定排名。在表格里看到分数后面有 ~ 或 ? 的,就是非 direct 的情况,心里要给它们打个轻微问号。这套机制让"新模型"和"小众模型"也能合理参与排序,又不至于盲目相信推断出来的分数。
6.4 显存估算公式
打分要参考"能不能跑得动",所以显存估算是底层的另一块基础设施。whichllm 的公式可以简化成这样:
显存占用 ≈ 权重大小 + KV 缓存 + 激活内存 + 框架开销(~500MB)
具体每一块怎么算:
- 权重大小:根据参数量和量化档位算(Q4 ≈ 0.5 字节/参数,Q5 ≈ 0.625,Q8 ≈ 1,FP16 ≈ 2);
- KV 缓存:
2 * 层数 * 隐藏维度 * 上下文长度 * 精度字节数,上下文越长这块越胖; - 激活内存:跟批次大小、隐藏维度相关,单用户对话场景比较固定;
- 框架开销:CUDA 上下文、库本身等等,约 500MB 兜底。
四块加起来,跟卡的可用显存一比,能不能放得下、要不要做"部分卸载",结论就出来了。
6.5 速度估算公式
速度这块更简单。本地推理大多数情况下是显存带宽瓶颈——每生成一个 token,都要把模型权重从显存读一遍走过计算单元。所以速度可以粗略估为:
tok/s ≈ 显存带宽(GB/s) / 单次推理需要搬运的权重(GB)
举个具体数字。RTX 4090 显存带宽 1008 GB/s,一个 7B 模型 Q4_K_M 量化大概 4.4GB,理论上限就是 1008 / 4.4 ≈ 229 tok/s。实际跑下来打个对折左右,因为还有计算开销、KV 读写、内存复制这些杂项。
工具内部就是用每张卡的带宽数据 + 模型权重大小,做一次粗估,加一点经验修正因子。这个估值跟实测一定有出入,但用来横向对比"哪个模型在我这张卡上更快",是足够准确的。
6.6 量化方式还有"质量惩罚"
最后一块要点:whichllm 不会把所有量化都当成等价的。
具体说,量化压得越狠,综合分会被扣一点点。Q8 几乎无损,零惩罚;Q5_K_M 轻微扣分;Q4_K_M 适中扣分;Q3 / Q2 这种压得很狠的,扣分就更明显。这套设计反映了一个现实经验——量化掉一档,benchmark 上的分数大概会跟着下滑几个点。
也就是说,同一个模型不同量化档位会出现在推荐里,工具会替你权衡"显存省下来的"和"质量损失的"。这点单从输出表格上看不太出来,但跑久了能感觉到——它推荐的量化档位几乎都很中庸,极端压缩档位除非你强行 --quant 指定,否则很少进 Top 5。
总结一句:whichllm 不是给你算了一个绝对数字,而是给了你一套自洽的相对排序。绝对数字(速度、分数)值得看个大概,相对排序值得放心相信,这一点心里有数就行。
七、选模型之前,先看懂显存是怎么花掉的
工具会帮你算,但你自己心里要有一本账。我在第二章提过"模型大小 ≠ 显存占用",这一章把这件事单独展开讲,让你以后无论用不用 whichllm,都能自己拍一个估算。
7.1 显存里到底装了些什么
把推理时的显存占用画出来,大致长这样:
┌──────────────────────────┐
│ 框架开销 / CUDA 上下文 │ ≈ 500 MB
├──────────────────────────┤
│ 激活值 / 中间张量 │ 几十 MB 到几百 MB
├──────────────────────────┤
│ KV 缓存(上下文) │ 随上下文长度线性增长
├──────────────────────────┤
│ │
│ 模型权重(最大头) │ 随参数量和量化档位变化
│ │
└──────────────────────────┘
最大的一块永远是权重,但很多人忽略 KV 缓存的存在——上下文一拉长,这块能直接吃掉好几 GB。所以当你想把上下文窗口从 4K 拉到 32K,别只看权重够不够,要把 KV 缓存的成本也加进去。
7.2 权重大小怎么算
公式比想象的简单:
权重显存 ≈ 参数量(B) × 每参数字节数
不同量化档位对应的"每参数字节数"大致是:
|
量化 |
每参数字节数 |
7B 模型权重大小 |
14B 模型权重大小 |
|
FP16 / BF16 |
2.0 |
≈ 14 GB |
≈ 28 GB |
|
Q8_0 |
1.0 |
≈ 7 GB |
≈ 14 GB |
|
Q6_K |
0.75 |
≈ 5.3 GB |
≈ 10.5 GB |
|
Q5_K_M |
0.625 |
≈ 4.4 GB |
≈ 8.8 GB |
|
Q4_K_M |
0.5 |
≈ 3.5 GB |
≈ 7 GB |
|
Q3_K_M |
0.4 |
≈ 2.8 GB |
≈ 5.6 GB |
|
Q2_K |
0.3 |
≈ 2.1 GB |
≈ 4.2 GB |
这张表是经验值,跟严格定义会有零点几 GB 的偏差,但够你做"信封背面的计算"了。
7.3 KV 缓存怎么算
KV 缓存的公式稍微复杂一点:
单 token 的 KV 缓存(字节)= 2 × 2 × 层数 × 头数 × 每头维度 × 精度字节数
↑ ↑
K和V 字节数(fp16=2)
- 第一个
2表示既要存 Ke