32G 的 Mac mini M6 买回来跑大模型,很多人第一反应是:终于可以在本地跑千问、Llama 这类模型,不用再被云端算力卡脖子。我自己走完一圈之后,最想说的是,本地跑大模型这件事,拼的根本不是“算力”,而是内存带宽。这篇内容不堆 PPT 参数,就从算力真相、真实 TPS 和端云决策三个角度,把 32G 这个配置在真实工作负载下的表现一次性说清楚。如果你是开发者、AI 产品经理,或者只是想把 Mac mini 当一台本地推理工作站,这篇应该能帮你省掉大量试错时间。
1. 32G Mac mini M6 的算力真相:别被芯片宣传带偏
1.1 大模型推理的剪刀差:算力强不等于跑得快
每次有人问我“M6 跑大模型到底行不行”,我都会先反问一句:“你说的行,是指每秒能吐多少字,还是指能不能把模型加载起来?”这两个问题答案完全不同。
从纸面看,M 系列芯片的 GPU 算力并不差,日常跑图像处理、视频编解码都很猛。但大模型推理的本质不是“算得多”,而是“搬得多”。每生成一个 token,都需要把整个模型的权重从内存搬到计算单元过一遍。这意味着推理速度几乎被内存带宽锁死,而不是被 FLOPS 锁死。
这里有个非常粗略但实用的估算公式:
tokens/s ≈ 内存带宽 ÷ 单次生成需要搬运的字节数
假设你运行一个量化到 Q4 的 7B 模型,大概要 4.5GB 权重,每次生成都要把所有权重扫描一遍。Mac mini 统一内存带宽保守点按 200GB/s 算,理论上限就是 200 ÷ 4.5 ≈ 44 tokens/s。实际还要扣掉系统开销、CPU 与 GPU 协同调度、KV Cache 增长等因素,所以真实值通常在理论值的 50%~70% 左右。这个数其实不算慢,但和“显卡 4090 跑 7B 能到 100+ tokens/s”一比,差距就出来了。
所以,算力真相的第一条:M6 不是不能跑大模型,而是它的瓶颈决定性因素从“GPU 多强”变成了“内存带宽多大、模型塞不塞得下”。
1.2 统一内存架构带来的优势与限制
Mac mini 的 32G 是统一内存,CPU 和 GPU 共享同一块物理内存。这和传统 PC 的“独立显存 + 系统内存”有本质区别。
优势非常明显:模型权重、KV Cache、中间激活值都在同一块内存里,省掉了显存和内存之间的拷贝过程。跑小模型时,加载速度快,切换模型也快,一个 7B 模型从启动到出第一个字通常只要一两秒。这种“随用随加载”的体验,是 Mac 生态独有的。
限制同样明显:macOS 系统本身、桌面环境、后台进程大概要吃掉 8~12G 内存。所以 32G 的机器实际能自由支配的,往往只有 20~24G 左右。这就意味着,如果你想跑一个 Q4 量化后就需要 30G 以上权重的模型,基本会直接触发交换到硬盘的操作,速度和体验会瞬间崩塌。
还有一个容易被忽略的点:M 系列芯片并没有传统意义上的“显存上限”,但它也缺少独立显卡那种专门的显存控制器。遇到超大模型时,你没法通过“显存不够就加显存”来解决问题,只能靠量化、减少上下文长度、或者直接换更小的模型来妥协。
我自己在部署时习惯用一条“黄金规则”:模型权重 + KV Cache + 系统预留,必须控制在物理内存的 70% 以内。超过这个红线,速度不是慢慢变差,而是直接断崖式下跌。
2. 量化精度与显存占用:FP16、INT8、INT4 怎么选
2.1 先搞清楚不同精度到底差多少
量化是本地跑大模型绕不开的话题。很多人一看到 INT4、FP16 就头大,其实理解核心就一句话:模型权重用多少位来存,影响的是内存占用、速度和精度。
| 精度 | 每个参数占用 | 一个 7B 模型的权重大小 |
|---|---|---|
| FP32 | 4 字节 | 约 28GB |
| FP16 / BF16 | 2 字节 | 约 14GB |
| INT8 | 1 字节 | 约 7GB |
| INT4 | 0.5 字节 | 约 3.5GB |
| Q4_K_M(混合) | 约 0.56 字节 | 约 4.1GB |
从表里能直接看出:同样的模型,FP32 下根本没法在 32G 机器上跑,INT8 能勉强装下 7B,Q4 则能把 13B 甚至 32B 都塞进内存。
精度选择上,我的经验是:聊天、摘要、翻译这类任务,INT4/Q4 和 FP16 的差异普通人基本感知不到;但需要模型做数学推理、代码生成、或者对输出质量要求很高时,INT4 会出现明显的逻辑漏洞和幻觉增多。所以高要求场景建议至少 INT8。
还有一个“精度越小速度越快”的误区:量化之后模型体积变小,每次生成需要搬运的字节变少,理论上速度确实会提升。但部分底层框架在反量化时需要额外计算,实际收益没有理论上那么大。真正最大的收益不是速度,而是“能装进内存”。
2.2 32G 内存到底能装下哪些模型
结合前面的黄金规则,我们按实际可用 22G 左右来算:
- 7B 级别:Q4 约 4GB,FP16 约 14GB,随便跑,还能开很长的上下文。
- 13B 级别:Q4 约 8GB,FP16 约 26GB。Q4 是甜点档位,FP16 则会非常勉强。
- 32B 级别:Q4 约 19~20GB,差不多到 32G 的极限边缘,能跑但上下文不能开长。
- 70B 级别:Q4 约 40GB,完全塞不下。即便开动态卸载,速度也会掉到不可用的范围。
我在实际使用中,13B Q4 是 32G Mac mini 上最舒服的组合。跑个 Qwen2.5 14B、Llama 3.1 系列,速度基本在 10~15 tokens/s,普通办公场景完全够用。32B 属于“可以跑但不舒服”的状态,适合做离线批量处理,不适合实时交互。
如果你想直接抄作业,我目前的主力配置是:日常对话用 7B Q4,代码和逻辑任务用 13B INT8,高质量长文分析直接调用云端大模型。这样既不浪费本地硬件,也不会被本地模型的智商上限困住。
3. 真实 TPS 测试与 TPS 虚高的坑
3.1 我的实测数据与测试方法
先明确一个概念:在大模型场景里,TPS 指的是每秒生成的 token 数(tokens per second),不是数据库里的事务数。但因为各家宣传口径不同,这个数字常常被注水。
我沿用的是最笨但最可靠的测法:让模型生成固定长度的内容,记录从第一个 token 到最后一个 token 的总耗时,然后除以 token 数。注意,只统计生成阶段,不统计首次响应前的预填充时间。
在当前 32G Mac mini 环境下,我的实测数据大概如下:
| 模型 | 量化方式 | 权重体积 | 实际 TPS(生成速度) |
|---|---|---|---|
| Qwen2.5-7B | Q4_K_M | 约 4.5GB | 25 ~ 35 |
| Llama-3.1-8B | INT8 | 约 8.5GB | 15 ~ 20 |
| Qwen2.5-14B | Q4_K_M | 约 9GB | 10 ~ 14 |
| Qwen2.5-14B | INT8 | 约 16GB | 6 ~ 8 |
| Qwen2.5-32B | Q4_K_M | 约 20GB | 4 ~ 6 |
| Llama-3.1-70B | Q4_K_M | 约 40GB | 1 以下,不可用 |
这里有一个很重要的对比:当 70B 模型超过物理内存时,TPS 会跌到 1 以下,基本就是“一个字一个卡顿”。遇到这种情况,别怀疑机器坏了,是内存带宽被交换操作拖死了。
3.2 影响 TPS 的隐藏因素与 TPS 虚高的坑
“TPS 虚高”这个现象,我见过太多次了。厂商宣传或者某些测试框架给出的数字,和实际使用感受差距很大。问题通常出在以下几个地方:
第一,预填充时间未计。有些评测把“从发请求到生成一个 token”的时间也算进去,那叫“首 token 延迟”,和每秒生成速度是两码事。如果两者混在一起算,数据会非常好看,但用户感知的是“等了很久才开始输出”。
第二,上下文长度不同。同一个模型,上下文从 4K 拉到 32K,KV Cache 会急剧膨胀,每多出一段历史对话,生成时就要多扫描一次 KV Cache。实际使用中长对话的 TPS 往往只有短上下文时的 60%~70%。
第三,量化格式不统一。Q4_K_M、Q4_0、GGUF 的 INT8,这些格式名称看着差不多,实际运行速度和精度差异巨大。所以你看别人报的 TPS,最好先确认对方用什么量化、什么推理引擎、什么上下文长度,否则没有可比性。
第四,并发推理的注水。服务端场景下,有些框架会把多个请求打包成 batch 一起推理,单请求的延迟变长了,但整体吞吐量上去了。对外宣称“TPS 500”没问题,但实际每个用户感受到的可能只有 TPS 5。
我的习惯是:拿到任何 TPS 数据,先问三个问题——有没有包含预填充?上下文多长?并发几个?三问之后,这个数字至少打七折再信。
4. 端云决策:什么任务留在本地,什么任务必须上云
4.1 一套可执行的决策流程
本地模型和云端模型不是替代关系,是分工关系。我的决策流程通常按四个维度走一遍:
第一步,看数据敏感度。如果是公司内部代码、客户隐私、个人日记这类不能外传的内容,只能留在本地,不管云端模型多强。
第二步,看响应延迟要求。本地模型首 token 延迟通常在 0.5~2 秒,云端模型受网络影响,首 token 延迟普遍 1~5 秒以上。如果任务需要快速反馈,本地占优。
第三步,看模型质量需求。复杂的逻辑推理、长文档总结、代码审核,这些任务对模型智商要求极高,本地 13B 和云端旗舰模型的差距是肉眼可见的。
第四步,算成本。云端按 token 计费,本地按电费和硬件摊销算。假设你每天跑 50 万 token,云端 API 一个月大概 50~200 元(取决于模型档位),本地 Mac mini 的硬件成本半年到一年就能摊回来。
把这四步走完,决策其实很清晰:高频、敏感、低难度任务放本地;低频、复杂、高难度任务放云端。这就是我理解的端云决策核心。
4.2 端云混合结构的落地姿势
我当前的生产环境就是一个典型的端云混合结构。
日常的邮件摘要、文章润色、草稿改写,直接走本地 13B 模型。反应快,数据不出本机,体验非常流畅。需要生成长文、做竞品分析、写复杂代码时,把请求转发给云端大模型。中间用一个统一接口层做路由,本地模型先判断自己能不能搞定,搞不定就自动转云端。
这种混合模式的另一个好处是:云端 API 出现故障或限流时,本地模型可以作为降级方案继续服务。虽然聪明程度下降,但至少业务不会断。反过来也一样,本地跑不动的超大模型任务,直接甩给云端,不用硬扛。
另外,本地模型还有一个容易被忽略的价值:当数据流水线。你可以用本地 7B 模型对海量文本做第一轮粗筛、标签、去重,把噪音过滤掉,只把真正有价值的部分送给云端。这样云端花费可能节省 80% 以上,而且速度快得多。算力不是用来硬撑的,是用来做预处理的。
5. 本地部署完整实操:从 Ollama 到 MLX
5.1 最省心的部署路线:Ollama
如果你不想折腾环境,我强烈建议从 Ollama 开始。它接管了模型下载、量化、运行、上下文管理这些脏活,一条命令就能把大模型跑起来。
# 安装 Ollama curl -fsSL https://ollama.com/install.sh | sh # 拉取一个 7B 模型试试 ollama run qwen2.5:7b跑起来之后,Ollama 会在 127.0.0.1:11434 开一个 OpenAI 兼容的 API 端口。这意味着你可以直接用任意支持 OpenAI 接口的客户端、插件、代码库来连接本地模型,零改造接入。
想要更精细地控制上下文和速度,可以调整模型参数:
ollama run qwen2.5:7b --verbose加--verbose会在结束时打印详细的速度统计,包括加载耗时、每个 token 的评估速度。实测数据章节里提到的 TPS 数字,我就是用这个方式记录的。
Ollama 的模型文件放在~/.ollama/models下,默认会扣减系统内存。如果发现模型运行速度异常慢,先看两个地方:一是系统内存占用是否接近 90%,二是不是同时跑了太多后台应用。遇到这种情况,我会把浏览器、通讯工具全部关掉,把内存让给推理进程。
5.2 Apple 原生方案:MLX 的正确打开方式
Ollama 足够日常使用,但要榨干 Mac mini 的推理性能,MLX 是绕不开的选项。MLX 是 Apple 自家的机器学习框架,专门针对统一内存架构优化,能利用 M 系列芯片的加速器,在长上下文场景下速度比通用方案更高。
MLX 的安装也非常简单:
pip install mlx-lm然后用一行命令生成文本:
mlx_lm.generate --model mlx-community/Qwen2.5-7B-Instruct-4bit --prompt "你好" --max-tokens 100MLX 和 Ollama 的区别在于:Ollama 是“开箱即用”,MLX 是“性能优先”。如果你的任务要跑很长的上下文,或者要用到 mlx-lm 的批量推理接口,MLX 会更适合。如果你的诉求就是日常对话、粘贴文本改写,Ollama 已经够用。
另一个相关项目是 llama.cpp,它支持 GGUF 格式模型,在 CPU 和 GPU 混合推理上很成熟。但在 Mac 上跑出最佳性能,还得靠 MLX。三者的选择建议是:快速上手用 Ollama,极致性能用 MLX,动手折腾、想理解底层机制就选 llama.cpp。
5.3 把本地模型接入代码与自动化工作流
本地模型最有价值的使用方式,是把它塞进你自己的代码和自动化流程里。我用 Python 做了个简单封装,统一对接 Ollama 的 API:
import requests def local_chat(prompt, model="qwen2.5:14b"): resp = requests.post( "http://127.0.0.1:11434/v1/chat/completions", json={ "model": model, "messages": [{"role": "user", "content": prompt}], "stream": True, }, stream=True, ) for line in resp.iter_lines(): if line: # 流式输出的每一行都存在 content sequence pass # 实际场景在这里解析增量内容 return full_text这样封装之后,本地模型和云端模型在代码层面就没有区别了。我可以把同一个函数名用在两个后端上,通过一个配置开关来切换路由。对上层业务来说,根本感知不到模型跑在哪。
这类接线模式对个人效率提升是巨大的。比如我在写代码时会挂一个自动化脚本,监听剪贴板变化,粘贴到编辑器之前先经过本地模型做一遍格式清理和错误提醒。整个过程不到一秒钟,因为走的是本地推理,没有网络延迟,体验上就像编辑器自带的功能。这是本地部署才能真正给到的爽感。
5.4 顺带说一句微调这件事
很多朋友看到“本地部署大模型”,下一步就会想微调。我想泼一点冷水:32G 的 Mac mini 能微调,但能调的规模非常有限。
如果做 LoRA 微调,7B 模型在 32G 上可以跑,只是训练速度偏慢;13B 模型会比较吃力,需要把批次压得很小;32B 以上基本不适合在本地全参数微调。
用 MLX 微调一个 7B 模型的 LoRA 大概是这个样子:
mlx_lm.lora --model mlx-community/Qwen2.5-7B-Instruct-4bit --train --data your_dataset --iters 200 --batch-size 1但我的实际建议是:与其折腾微调,不如把精力放在提示词工程和上下文工程上。本地 13B 模型在提示词调优之后能完成很多“看似需要微调”的任务。微调的成本很高,效果却不一定比精心设计的 prompt 更好,优先把提示词做到极致,再考虑动训练数据。
6. 实测中遇到的常见问题与排查方法
6.1 模型加载慢,生成第一个字要等很久
这个问题通常是两个原因:一是模型体积太大,加载到内存需要扫描大量数据;二是首次推理时系统要做很多初始化工作,包括算子适配、图优化等。
排查方法很简单:用 Ollama 的--verbose看加载耗时和评估耗时。如果加载时间占了总时间的 80%,说明模型对内存来说太大了,要么换小模型,要么换更激进的量化方式。如果加载很快但首 token 慢,问题出在预填充阶段,检查上下文长度是不是开得太长。
6.2 上下文一长,速度骤降
这是最容易被忽视的问题。很多人测试时只跑几句短对话,觉得速度还不错,一旦开始长篇对话,速度能掉一半以上。
原因在于 KV Cache 随上下文长度线性增长。每多生成一个新 token,都要把之前的 KV Cache 全部读取一遍。上下文从 2K 提升到 16K,KV Cache 占用会翻好几倍,推理时读取的数据量也同步上涨。
处理方法:首先确认你设置的上下文长度是否真的需要那么大。如果任务只需要处理 5000 字文档,就没必要开 32K 上下文。其次,在 Ollama 里可以通过num_ctx参数控制模型使用的实际上下文长度,不要捧着系统默认的 2048 不优化,也别一口气拉到 32K。
6.3 内存不足的多种表现形式
32G 内存跑大模型,内存不足不是“系统弹窗报错”这么简单。实际表现往往更隐蔽:
第一种是生成速度突然跌到 1 tokens/s 以下,CPU 占用却飙到接近满载。这是典型的内存交换状态,系统在硬盘和内存之间反复搬运数据,比直接报错更令人崩溃。
第二种是模型加载到一半直接退出,没有任何提示。有时是因为mmap映射文件失败,有时是因为内存分配被其他进程抢占。
第三种是系统开始疯狂使用 swap,内存压力指示变黄甚至变红,整个 Mac 变得卡顿。
我的排查套路是:先top -o mem看内存占用排序,确认模型进程占了多少;再用vm_stat看内存压差。如果发现模型权重 + 其他进程已经超过 25G,果断降量化等级或者降模型规模。在 32G 机器上跑本地模型,学会“认怂换小”是一种美德。
6.4 同一模型在 Ollama 和 MLX 中速度差异很大
这不是玄学,是两种推理引擎的底层实现差异。Ollama 底层是 llama.cpp,它要兼容多种硬件平台,在指令调度和内存访问模式上做了很多通用化权衡;MLX 则针对 Apple Silicon 做了专门优化,能更有效地利用统一内存带宽。
所以如果你追求极限性能,同一个模型在 MLX 下可能跑得更快。但 MLX 的问题在于生态相对封闭,支持的模型格式和工具链不如 Ollama 丰富。我的建议是:日常使用 Ollama,遇到长上下文或批量任务时切换 MLX,两个工具并行部署,互不冲突。
最后分享一个实际使用中的小技巧:给本地模型单独开一个 macOS 登录用户,所有 Ollama/MLX 的推理进程都扔到这个用户下跑。主用户正常办公,推理用户专注跑模型,两者内存互不干扰。这样即使推理任务把内存吃满,也不会拖垮我在主用户里的工作状态。我用这个方式跑了半年多的 7B + 13B 双模型常驻,体验一直很稳定。
另外,很多朋友会纠结“我的场景值不值得配一台 32G Mac mini”。我的答案是:如果你每天都要和 AI 交互、需要处理私密数据、或者想彻底摆脱按量付费的束缚,那它物超所值。如果你只是偶尔尝鲜,建议还是先用云端 API,别让硬件吃灰。