乐于分享
好东西不私藏

一篇文章说清楚 AI 模型本地部署的参数与坑

一篇文章说清楚 AI 模型本地部署的参数与坑

Qwen3.8-27B模型发布后,全网都很激动,各类博主都在评测性能,甚至有说把opus4.6装进了本地笔记本里,端侧崛起的时代来了(包括我)。折腾一番之后,我发现实际并不不是这回事。并且花了些时间把本地部署 AI 模型的坑给你数理清楚。

很多人第一次在本地跑大模型,是从 Ollama 开始的:装好之后 ollama run 一条命令,模型就能聊。这一步体验确实简单,但只要往前多走一步——想换个模型文件、想调设置,或者换到 Mac 上找个更快的方案——就会撞上一面名词墙:GGUF、Q4_K_M、KV Cache、上下文长度、PP/TG、MTP、量化……

这篇文章把这面墙一块块拆掉。拆法借参数页:设置里每一个旋钮都对应大模型工作时的一个具体环节,把旋钮讲明白,模型在你机器上到底在干什么,也就跟着讲明白了。讲完之后再往外看两步:为什么说到底拼的是内存带宽,为什么 Mac 统一内存还是替代不了 N 卡,以及参数全调对之后,本地到底适合干什么。

一、先分清:引擎、模型、格式

Ollama 扮演的角色是推理引擎(inference engine):把模型文件装进内存,接收请求,算出下一个 token,再管理上下文和接口。它本身没有模型——ollama pull 下来的才叫模型。

同类引擎不止它一个:

名字
定位
llama.cpp
开源 C++ 推理库,Ollama 的底层,CPU 起家,现在各类 GPU 都支持
Ollama / LM Studio
在 llama.cpp 上包了一层的易用外壳,一个命令行、一个图形界面
vLLM
面向服务器的引擎,主打高并发,continuous batching 的出处之一
MLX
Apple 官方的机器学习框架,专门吃 Mac 的 Metal 和统一内存
oMLX
基于 MLX 的 Mac 一站式推理引擎,我现在用的

模型文件还有格式之分。llama.cpp 一系用 GGUF(单文件,文件名带 Q4_K_M 这类后缀);MLX 一系用自己的目录格式。同一个模型可以转成两种格式,权重内容一样,就像同一段视频存成 mp4 或 mkv——引擎只认自家格式。

顺带把最基础的两个词说清:

权重(weights):模型的本体,训练学到的几十亿个数字。27B 的意思是约 270 亿(Billion)个参数。模型文件的大小,大致等于参数量乘以每个参数占的字节数。

统一内存:Apple Silicon 的 CPU 和 GPU 共享同一块内存,不用来回拷贝,但总量也就那么多。后面所有的内存烦恼,都从"总量有限"这四个字来。

在 Mac 上,Ollama 能用,走的是 llama.cpp 的通用路径;MLX 系是 Apple 自家路线,对 Metal 和统一内存的调度更贴。我最后留在 oMLX,下文参数也以它为例——但名词是通用的,llama.cpp 一系完全对得上。

二、模型在你机器上做什么

Token:模型不认识字。tokenizer 先把文本切成 token——词、词根或标点的小段——每个 token 对应一个编号。"上下文 128K"说的就是 128 千个 token,对中文大致是几万到十几万字。

模型收到你的消息后,完整过程分三步:

  1. 1. 把 system prompt、全部对话历史、你的新消息拼成一条长文本,切成 token;
  2. 2. Prefill(预填充):一次性把这串 token 全部读入,为每一层算出并保存 Key/Value,也就是 KV Cache;
  3. 3. Decode(解码):基于 KV Cache 一个 token 一个 token 往外猜,每出一个就拼回去猜下一个,直到撞到停止条件。

两个阶段的速度天差地别。Prefill 是一大批 token 同时做矩阵乘法,天然并行,能到几百上千 tok/s;Decode 每步只算一个 token,还要回看全部历史,串行等待,几十 tok/s 就不错。一台 48GB M5 Pro 跑 27B 的典型值:PP 350–390,TG 18–20。

参数页和评测里反复出现的两个速度指标就是它们:PP(Prompt Processing,读入速度)和 TG(Token Generation,生成速度)。你体感的"打字快不快"是 TG;看到"吞吐提升 X%"的宣传,先问提升的是哪一个。

三、内存四笔账

运行一个大模型,内存里同时压着四笔东西:

Memory ≈ Weights(权重)+ KV Cache(历史缓存)+ Prefill Buffer(读入临时缓冲)+ Runtime(引擎和系统开销)

Weights:27B 用 BF16(每个参数 2 字节)存要约 54GB,超过一般消费级 Mac;4bit 量化后约 13.5GB。这是 27B 能进 48GB Mac 的前提。

KV Cache:Transformer 的注意力(attention)机制要求每个 token 都能"回看"前面所有 token。为了避免每步重算,每一层都把历史 token 的 Key/Value 向量存下来,上下文越长这份缓存越大,基本线性增长。(架构层面还有 GQA——多个查询头共用一组 KV——给它瘦过身;量化是第二刀。)一台 48GB Mac 跑 4bit 27B,大约 45K 上下文撞内存上限,这是算术结果,不是故障。

Context Window:模型架构允许的最大上下文,比如 131072。它说的是"最多",不担保你的机器装得下——"模型支持 128K"和"这台机器能跑 128K"是两件事。

Memory Guard / wired limit / swap:macOS 限制 GPU 可锁定的统一内存,引擎还会自设安全上限,预测峰值超限也会拒绝继续 prefill。引擎拦你,是为了不让系统进 swap:一旦越界,紧接着就是 Metal OOM 和进程被杀。macOS、IDE、浏览器的口粮仍然要留。

四、量化:所有 Q 开头名词的统一解释

量化的意思一句话:用更少的 bit 存本来的数字。一个权重原本 16 bit,压到 4 bit,体积剩四分之一,代价是精度损失。bpw(bits per weight)就是平均每个权重用几 bit,这个数越低越省内存、越伤质量。

Ollama 用户最常见的是 GGUF 文件名里的后缀。Q4_K_M 拆开读:4bit、K-quant(把权重分成分组、各组分别压的分块量化)、M(medium,块大小档位)。Q8 是 8bit 整体量化,F16 是不量化。数字越小越省内存、越伤质量。

MLX 这边对应两档。MLX 4bit 把所有适合量化的层统一压到 4bit,简单、kernel 快。oQ4 / oQ4e 是数据驱动的混合精度:量化前先跑 calibration,测每一层对误差的敏感度,钝感的层压 4bit,敏感的层保留 5/6/8bit,平均约 4.6 bpw;oQ4e 再做一轮误差补偿,连"权重该怎么舍入"都一起优化。oQ 系是质量优先:内存接近普通 4bit,能力保留更多,速度未必更快。

KV 也能量化:TurboQuant KV 把 KV Cache 从 FP16 压到 8bit(省一半)或 4bit(剩四分之一)。KV 是模型回看历史的凭证,Agent 要从几十 K 之前找回函数名和 tool result,压得太狠会伤这种"翻旧账"的能力。

NVFP4 单独说:同样叫 4bit,但它的加速依赖 NVIDIA Blackwell 的 FP4 数值格式和 Tensor Core 原生执行,是 RTX 5090、B200 那批卡的专属路径。Mac 没有这组硬件,格式再好也没有 kernel 替它跑。判断任何量化方案,看三件套:格式 × kernel × 硬件。

五、加速开关:每个都在撬一个具体瓶颈

MTP(Multi-Token Prediction):生成慢的根源是自回归——猜一个、拼回去、再猜一个。MTP 让模型一次给出多个候选,自己验证后一次接受多个。输出分布不变,属于无损加速。Qwen3.8 原生支持,是最值得开的一个。

DFlash / speculative decoding(投机解码):换一个小的 draft model 来猜,大模型批量验证。收益取决于 acceptance(每次验证真正接受几个 token):猜 5 个只收 2 个,其余白算。代码续写这类好猜的任务收益高;reasoning、tool calling 的 token 分布难猜,收益缩水。同机实测:DFlash2 在 16.3–23.3 tok/s 之间波动,MTP 稳定 18–20,没有拉开差距。两者在 oMLX 里互斥,不能叠加。

ANE(Apple Neural Engine):Mac 里的 NPU。oMLX 可以把一部分 prefill 卸给它,但它只加速 PP,且额外占内存。本地场景 PP 本来就快、TG 才是瓶颈,这项通常不值。

Prefix Cache:Agent 每轮请求的前缀——system prompt、项目说明、历史对话——全是一样的,命中缓存就跳过这段的重复计算。注意边界:省的是计算,当前活跃上下文的 KV 一分不少。

Chunked Prefill:把长 prompt 切片,穿插在生成间隙读入。不开的话,一个 30K 的 prefill 能把正在生成的请求卡到 0.3 tok/s。

Flash Attention / SDPA:注意力计算的高效实现,不在显存里铺开完整注意力矩阵,省内存也省时间。参数页里看到它多半默认开着,不用动。

六、参数页上剩下的量

Temperature(温度):采样随机度。0 表示每步都选概率最高的 token,稳定但容易重复;数值越大越发散。推理类模型常用 0.6 上下。

Max Tokens:单次最多生成多少 token。它和 Context Window 是两个量——后者是输入加历史加输出的总空间。"已达到输出上限"只是这一轮写超了,和内存无关。

并发 / continuous batching:引擎可以同时接多个请求共享 GPU。但单用户开大并发不会让单个任务变快——20 tok/s 开 4 路还是四路分带宽,单路更慢。单 Agent 用 1,带 subagent 试 2。

Auto Compact:不在引擎这边。对话历史怎么组织、何时总结压缩,是上层 harness(Claude Code、OpenCode 这类工具)的职责。Context Window 设成 128K,不会有谁自动在 60K 时帮你总结。

七、四笔账算完,真正的墙是带宽

参数页看懂之后,可以回答一个更根本的问题:Decode 为什么就是快不起来?

Decode 每生成一个 token,都要把全部权重从内存读一遍。4bit 的 27B 权重约 13.5GB,M 系 Pro 档的统一内存带宽在 270 GB/s 上下,做个除法:270 ÷ 13.5 ≈ 20 tok/s。和实测的 18–20 正好对上——TG 的天花板,卡在内存带宽上。

Prefill 为什么快?几百上千个 token 一起算,读一遍权重能做海量乘法,瓶颈从带宽换成了算力。这就是计算机体系结构里的 roofline:每读一个字节能做多少次运算,决定你卡在哪堵墙。

所以三种资源各管一段:容量决定模型放不放得下,带宽决定生成有多快,算力决定 prefill 有多快。这也顺手解释了两个日常现象。上下文越长 TG 越慢,因为 attention 每步还要回读全部 KV,要读的东西变多了;MTP 为什么有效,因为一次验证一批候选 token,权重读一遍能出多个字,等于把带宽利用率翻了几倍。

量化在这里显出第二重身份:4bit 同时是容量优化和带宽优化——它把每 token 要读的字节数也压到了四分之一。MoE(混合专家)架构同理:DeepSeek 那类 671B 的模型每个 token 只激活几十 B 参数,读的权重少了,速度就上去了。近几年模型架构的演化,有一半是在绕这堵带宽墙。

八、Mac 统一内存的能与不能,和折腾党的玩法

统一内存买到的是容量。CPU 和 GPU 共享同一块,不用买两份。Apple 的内存定价也比显卡显存便宜:48GB 的 MacBook、192GB 的 Max、512GB 的 Studio,都是 N 卡摸不到的容量档位。Mac 也确实能靠这个跑别的机器装不下的模型。

但它买不到带宽。M 系 Pro 档约 270–300 GB/s,Max 约 500,Ultra 约 800;N 卡那边,一张 RTX 5090 的 GDDR7 是 1.8 TB/s,数据中心卡用 HBM:H200 约 4.8 TB/s,B200 到 8 TB/s,和 Mac 差出一个数量级。同一个 4bit 27B,Mac 跑 20 tok/s,5090 能到 100 上下。再加上 Tensor Core 管 prefill 算力、NVLink 管多卡扩展,追求速度和规模化,最后还是要回到 N 卡。

两边的生态位就此分开:N 卡拼速度,Mac 拼容量、静音和功耗。折腾党的玩法也基本落在这个坐标系里:

  • • 二手 3090 ×2,48GB 显存,桥Link,是经典的性价比 rig;
  • • 淘数据中心退役卡,显存大、带宽高,代价是噪音、功耗和自己改散热;
  • • 国内市场有改装 48GB 显存的 4090,容量翻倍,稳定性风险自担;
  • • Mac 阵营的玩法是堆容量:几台 Mac mini 用雷雳连起来跑 MLX 分布式推理,或者一台 512GB 的 Mac Studio 硬扛 671B 的量化 MoE——消费级硬件里能装下这个模型的,屈指可数;
  • • SSD 也算一级存储:模型加载靠 mmap,KV 的冷数据可以溢写到 SSD(oMLX 的 Cold Cache 就是干这个的),把快速内存留给热数据。

九、拼回一张地图

名词按四笔账和两个速度指标归位之后,配置顺序自然浮现,从收益最稳的往下排:

  1. 1. 权重量化,先让模型进内存(oQ4e / MLX 4bit / GGUF 的 Q4_K_M);
  2. 2. Context Window 设 64K 而非 128K,给 KV 留增长空间;
  3. 3. KV 量化用 8bit;
  4. 4. 开 MTP 提生成速度;
  5. 5. Prefix Cache 省重复 prefill;
  6. 6. Chunked Prefill 开、并发 1–2;
  7. 7. ANE、DFlash 这类实验项,等前面全稳了再碰。

一台 48GB Mac 跑 27B 的可用起点:oQ4e 权重、64K 上下文、KV 8bit、MTP 开、单并发、chunked prefill 开。再留一条余量原则:最舒服的状态不是把内存吃满——Agent 随时可能塞进一段长工具输出,headroom 本身就是性能。

把视角拉远一点。这篇文章里出现过的所有优化——量化、KV 压缩、MTP、MoE、Prefix Cache——都在绕同一堵墙:内存的容量和带宽。这堵墙也正是当下存储行业最热闹的地方。数据中心卡的 HBM 一代代往上堆(HBM3e、HBM4),三家存储厂的产能被 NVIDIA 提前锁定;LPDDR、GDDR、HBM、SSD 正被大模型整理成一条完整的存储层级——热的放 HBM,温的放显存,冷的落 SSD。本地玩家在参数页里拧的每个旋钮,和存储厂商在财报里讲的每个故事,是同一件事的两面:带宽不够,就用层级来换。

十、最后想清楚:本地到底适合干什么

一轮用下来,结论有点泼冷水:Qwen3.8-27B 的能力在本地是达标的,写代码、查资料、当 Agent 都够用;但性能这一关,消费级硬件过不去。卡着的是三件事。

速度。TG 20 tok/s,云端旗舰 API 的流式输出普遍有它的几倍。单轮问答感觉不明显,Agent 一轮任务动辄几千 token 输出,等待时间被放大成几倍。

上下文。模型标称 128K,这台机器 45K 撞墙,64K 已是精打细算的实用上限。Agent 恰恰是上下文大户:历史对话、工具返回、代码文件,一轮任务随便吃掉几十 K。官方支持的长度和你能开的长度,中间差着一个身位。

并发。单请求独占刚好,主 Agent 带一个 subagent 勉强,再往上多个 active KV 抢内存、互相拖慢。云端一个账号后面是成排的 GPU,本地是一块内存自己扛。

所以本地的定位要想清楚:它和云端各管一摊。下面这些场景是本地真成立的:

  • • 隐私和合规的硬约束:代码、文档、客户数据不允许出机器。这是最硬的需求,慢也得用,没有替代方案;
  • • 对延迟不敏感的批量任务:批量摘要、打标、清洗、翻译,睡前挂着跑,电费按度算、token 不要钱。云上按 token 计费,量一大就是真金白银,批处理恰好不在乎慢;
  • • 离线环境:没网、网络不稳、数据不能过公网的地方,本地是唯一选项;
  • • 折腾和学习本身:换模型、调参数、把每一层拆开看,只有本地做得到——这篇文章就是产物。

反过来,重度 Agent 长任务——上下文 100K 起步、要速度、要多路并发——目前就是云端旗舰的领地,本地的 64K + 20 tok/s + 并发 1 能用,体验差一截。

一条简单的判断线:延迟敏感、质量优先的交互任务交给云;隐私硬约束和不在乎快的批量任务留给本地。想清楚自己落在哪边,再决定折腾到什么程度。

补一句:普通笔记本的转机,在 MoE

如果上面把本地说得有点劝退,这里有个正在变好的变量。前面算带宽、算容量,默认的全是"稠密模型"——生成一个字,都得把全部权重读一遍。MoE(混合专家)做了一件事:把速度和容量解耦。

看 Qwen3.5-35B-A3B 这类 35B-A3B 模型:35B 是总参数,4bit 量化后约 17GB,这是它能进内存的门槛;但每个 token 只激活约 3B——top-8 路由,256 个专家里一次只挑 8 个出来算,这也是"叫 A3B"的来历。于是决定生成速度的,不再是总参数,而是被激活的那一小撮。普通笔记本的带宽只有 M 系的零头,可只要被激活的权重够少,每读一遍要做的乘法就少,tok/s 照样能爬起来。

MoE 的代价也要说清:那 248 个没被挑中的专家,权重照样得压在内存里。所以它省的是"算得少",不是"装得少"——容量那道门还在,普通本还是得买得下这 17GB。但速度这道坎,机器第一次有了谈判的筹码:带宽不够,靠"少激活"来凑。这篇文章里我自己日常跑的,正是这条路线上的 Ornith-1.5-35B-A3B(35B 总量、3B 激活、oQ4e 混合精度)——3B 激活的密度,和稠密 27B 确实不是一条赛道。普通笔记本用户先别急着上重家伙,这条线值得再等一等。


(本文经 OMLX/Ornith-1.5-35B-A3B-oQ4e-mtp 辅助完成)