跳转至

第 12 节 · 48GB 的 Mac,到底能跑多少 AI

一台 48GB 内存的 MacBook Pro,白天要写稿、跑数据、查询量,晚上还要本地跑模型。这一节回答一个特别具体的问题:它到底能同时装几个 AI,各自装哪一类。

先把丑话说在前面。网上很流行一种写法——"内存账单实测""峰值多少 GB",再配一张漂亮表格。这一节不给你这种东西,因为我没做过那样一次测量。

能拿出硬数字的只有两件事:文生图到底有多慢,和语音合成怎么把我坑了一把。其余的,是配置里写下的内存预算,不是采样实测。这两个词——预算、实测——我会一路分清楚,因为它们差着一个"我有没有真的看着内存表记过数"。

一、我装了哪 5 个

我把本事不同的 AI 分成了五个岗位,全部本地推理,数据一步都不出门:

  • 代码:Qwen2.5-Coder-7B 的 4-bit 版,写代码、解释代码都靠它
  • 语音转写:whisper-medium,把录音转成文字
  • 视觉理解:Qwen2.5-VL-7B 的 4-bit 版,看图、读图
  • 语音合成:kokoro(82M),把文字念出来,是个特别小的模型
  • 文生图:FLUX.2-Klein-4B,把一句话画成图

为什么是这五个?因为它们刚好盖住一个人干活时最常用的五类动作:跟文字打交道(写码)、把听来的变成文字(转写)、把文字变回声音(合成)、看图(理解)、出图(生成)。

这五件事,过去每一件都得开一个网页、登一个账号、把材料传上去。它们不是不能用,是"用一次就多一份材料躺在别人服务器上"。现在这五类动作,全都收进了这一台机器。

还有一层考虑:这五个的能力档次是"够用"而不是"最强"。它们顶不住顶配云模型的活儿,但它们便宜地守着一条底线——日常那些不值得上传的活,全在本地办掉。 这就够了。

它们各自的引擎还不一样:前四个跑在 MLX 上,文生图走的是 PyTorch 的 MPS——因为文生图那条管线当时在 MLX 生态里还没有成熟实现。

这五个不是我硬塞进去的。真正动脑子的是下面这件事:它们不是五个一起住进内存,而是有值班表的。

二、它们怎么分内存:预算,不是实测

先说这个认知差距,它是很多人不敢在本地搭东西的根源。

五个模型不等于五份内存常年趴着。 我的分法是:轻的常驻,重的按需,闲着就自动下班。代码、转写、合成这三个轻的长期值班;视觉理解和文生图这两个重的,收到请求才加载,用完就卸——视觉理解空闲 120 秒卸载,文生图空闲 180 秒卸载。

而且这两个重的还共用同一块按需内存,不会同时上岗。道理很简单:一次只能干一件重活的时候,你不需要给两个重活各留一整间厂房。

像一家公司:三四个全职坐班,两个外聘随时叫。你不会为了"万一要拍视频",常设一个摄制组在办公室里天天开着灯。

那怎么判断谁该常驻、谁该按需?两个变量:用得频不频,和加载快不快。天天要叫、加载又慢的,就得让它在岗;偶尔才用、又占地方的,随叫随到才划算。这份判断做对了,值班表就立住了。

下面这张表,是配置里每个模型自己声明的内存占用,加上 KV cache 和系统占用的估算——是预算,不是采样:

岗位 模型 配置内存预算 上班方式
代码 Qwen2.5-Coder-7B(4-bit) 约 5GB 常驻
语音转写 whisper-medium 约 1.5GB 常驻
语音合成 kokoro(82M) 约 0.3GB 常驻
视觉理解 Qwen2.5-VL-7B(4-bit) 约 6GB 按需,空闲 120 秒卸载
文生图 FLUX.2-Klein-4B 约 8GB 按需,空闲 180 秒卸载
系统本身 — 约 5GB —
KV cache — 约 3-5GB —

图 B-12-1(待出):五个 AI 的值班表——三个轻的长期坐班,两个重的随叫随到,闲置自动下班

把常驻那几项加起来,配置预算落在 约 15-17GB。这意味着什么?48GB 的机器,去掉常驻和系统,还空着大半。所以这套东西的瓶颈,从来不在一台 48GB 的 Mac 装不装得下,在你会不会排这张值班表。

我为什么要反复强调"这是预算不是实测"?因为预算管的是"最坏情况装不装得下",不管"平时到底多舒服"。 预算把系统占用、KV cache、峰值全算进去,图的是保证绝不撑爆;真实占用是另一回事,得靠采样才知道。

我没采,所以这一节就不写"峰值多少 GB"——宁可少一个漂亮数字,也不编一个。 你要是真想看内存,打开活动监视器自己看五分钟,比抄我一张表可信得多。

三、最慢的一环:文生图

前面那五个岗位,真正让我有硬数据可讲的,是文生图。因为它有原始日志,每一张图都记了耗时。

同一台机器上,只改输出尺寸,耗时是这样:

输出尺寸 耗时
512×512 约 9.4 秒到 11.6 秒(同批几张样本)
768×768 约 35.0 秒
1024×1024 约 62.9 秒(常规批 7 张在 62 到 63 秒);慢的批次里最慢一张 201.5 秒

看这组数,第一反应往往是"还行啊"。但把像素摊开算就变了:从 512 到 1024,画面边长翻一倍、像素涨到四倍,时间却从 10 秒涨到 63 秒——涨了六倍多。 从 512 到 768 也一样,像素只多两倍多,时间多了三倍半。

也就是说:图这个东西,不是"慢一点",是"每大一号,慢得比你以为的还多"。

为什么会这样?因为出图和"写一段话"根本不是同一种工作。写东西是一次一个字往前吐;出图是拿一整张画布一遍遍重画——分辨率翻一倍,每一遍要处理的像素就翻一倍,而且画的遍数还不减。

写稿是打字,出图是漆一整面墙,还是反复刷好几遍的那种。 一个字的活儿和一面墙的活儿,时间不是一个量级。

图 B-12-2(待出):同样是出一张图,尺寸每大一号,时间涨得比像素还快——512 到 1024,像素四倍,耗时六倍多

所以在这套系统里,图生是最慢的一环,没有之一。它不是给你"边聊边出图"用的,是给你"把需求丢进去、先去干别的、回头来取"用的。它在五个岗位里排最后,不是能力问题,是它的活儿本来就是这个量级。

四、踩过的坑

部署这几个模型踩的坑,比正文任何一个数字都真实。

第一个坑,一个库的初始化姿势。 接语音合成的时候,我照直觉直接构造那个模型对象,结果连续四次启动,四次倒在同一个地方——报错说它缺四个必需参数(模型、配置、声库管理器、模型路径)。我当时以为是参数没给全,补一个又一个,补不齐。

真相是姿势错了:这个库不让你直接造,得先用它的加载方法把东西读好,再交给它。不是参数少给了,是入口站错了。 一个初始化写法,换来四次启动失败——四个参数明晃晃写在报错里,偏偏没一个是你要手动补的。

第二个坑,两个模型抢同一个底层库。 代码模型和视觉模型,对同一个底层库的版本要求正好相反:一个要求低于 5.0,一个要求不低于 5.0。装在一起就互相踩。解法很土但很稳——各自住进独立的运行环境,谁也别碰谁。当时是 5 个岗位、5 套环境。

这种"独立环境"不是洁癖,是止损:代价是磁盘和安装时间变多,好处是任何一个模型升级,都不会顺手炸掉别人。一群人挤一间办公室,一个人搬家具全楼遭殃;一人一间,各自折腾。

第三个坑,Docker 碰不到 GPU。 我一开始想把所有服务都塞进 Docker 里统一管。结果发现:Docker 在 Mac 上是跑在一台 Linux 虚拟机里的,它根本摸不到 Apple 的 GPU。 这不是配置没调对,是它压根在另一台"借来的电脑"上。

最后的分工是——Docker 只当总机(做 API 网关,统一收发请求),真正跑模型的进程,全部待在 macOS 原生环境里,直接够得着 GPU。总机在楼上接线,干活的都在自己家装机,谁也别隔着门禁使唤。

三个坑有个共同点:它们都不是"能力不够"造成的,是"位置没摆对"。 参数位置、环境位置、容器位置——本地部署真正的门槛,从来不在模型本身。

五、这套东西适合谁

三个岗位(代码、转写、合成)随时叫随时有,两个重岗(看图、出图)按需加载。这套配置适合的场景很明确:

数据不出门、本地自用。 你的录音、你的图、你的代码,全在本地机器上跑完,一个字节都不上云。

不是拿来和云厂商打价格战的。 云上模型更大、更快、更省事,这是事实。本地这套赢的不是单价,是"东西没离开过我的机器"。你如果只是想省钱,买本地硬件算下来多半不划算;你要是图"数据不出去",它才成立。

换句话说,先想清楚你要的是哪一样:要"更强的脑子",去云端;要"不出门的脑子",才回本地。 两件事的答案不同,选择就不同——别用省钱的尺子量一套本来就不为省钱搭的东西。

具体到岗位分工:

  • 代码、转写、合成:轻、常驻、随时可用,适合当日常工具天天叫
  • 看图:按需,够快,适合穿插着用
  • 出图:慢,适合"能等"的离线任务,别指望实时交互

一句话:这套东西的价值不在"更便宜",在"更干净"——你的数据,从没离开过这台机器。

尾声

回头看,这一节其实是整本书里最"底层"的一节。

按 AOSI 那张七层图,模型、算力、数据这三样叠在一起,是 L1 基座层——最下面那层,是"物质",是所有智能动作真正落地的地方。上面的工具层、工艺层、个体层、协作层,再热闹,脚下踩的都是这层。L1 没铺好,上面每一层都是空转。

把算力搬回家,搬的就是这层基座。它不炫,甚至不便宜,但它决定了你上面那家"一人公司",到底是在别人的地基上盖房,还是在自己的地基上盖房。

——而自己有没有地基,平时看不出来,断网那天就全看出来了。

口径说明:本节里的内存数字,除文生图耗时与语音合成报错外,均取自部署配置中声明的预算值,非内存采样实测;文生图耗时为同机、分多批采样记录,样本量不大,只作量级参考。