作者报告使用 Project Maya 与 EXL3,在 RTX 5090、128GB 内存机器上运行 GLM-5.3-Flash,配置 512K 上下文,速度约每秒 25 token。文章讨论量化权重的内存压力,以及活跃参数量和 CPU、PCIe 数据搬运对速度的影响。
GLM-5.3-Flash 是一个 321B(3210 亿参数)的混合专家模型,它的 3.05 bpw EXL3 量化版本大小为 125 GB,我这台工作站的内存只有 128 GB,留出操作系统所需的空间后,根本装不下。但它依然能在本地运行:一张 RTX 5090、128 GB 内存,支持 512K token 上下文,速度约为每秒 25 个 token。这篇指南会介绍如何用 Project Maya 做到这一点,以及我们在这个过程中测得的数据。
下文所有数据均于 2026 年 10 月 15 日在我们自己的机器上测得。引用他人的数据时,我会注明来源。
这是两篇系列文章中的第二篇。第一篇介绍了如何用 Strata 以每秒 79 个 token 的速度运行 Qwen3.8-Flash-Next;在那之前,我还写过一篇文章,介绍如何用 EXL3 和 TabbyAPI,在 40 多 GB 内存上运行 Qwen3.8-Flash-Next。
GLM-5.3-Flash 是 zai-org 以 MIT 许可证发布的开放权重模型。Maya 的 README 将其描述为:总参数量 321B,每个 token 激活约 18B 参数,上下文最长支持 1M token。它采用混合注意力设计,并带有一个用于草拟 token 的 MTP 层。
18B 的激活参数量,大约是 Qwen3.8-Flash-Next 模型卡所列 6B 的三倍。这解释了下文大部分速度差距:每生成一个 token,都有更多模型数据需要经过 CPU 和 PCIe。
我首先尝试了 TabbyAPI,搭配 turboderp 的 GLM-5.3-Flash EXL3 量化版本。ExLlamaV3 将 CPU 专家放在内存 arena 中,没有用于存放专家的 SSD 层。因此,整个模型必须装进显存和内存,同时还要给操作系统留出空间。在 128 GB 内存上,能够运行的最大量化版本是经过自校准的 2.60 bpw 修订版:
3.05 bpw 量化版本大小为 125 GB,用这种方式装不下。你需要一个能够把部分专家留在 SSD 上的运行时。
Project Maya 是 Strata 的一个分支,专门为这一个模型打造。它的引擎把对话中最常用的专家放在 GPU 上,次常用的放在内存里,其余放在 NVMe 硬盘上,并在聊天过程中动态搬运。它会测量硬件性能并自动调优,提供兼容 OpenAI 和 Anthropic 的 API,还带有一个可以实时监控的仪表盘。
Maya 提供自己的 GGUF 量化版本:Maya-S 为 96.5 GB,Maya-M 为 116 GB,Maya-L 为 156 GB。它也可以直接从 turboderp 的 safetensors 文件中读取 EXL3 量化权重,README 将这项支持标记为实验性功能,且仅支持 NVIDIA。我选择 EXL3 3.05 bpw 这条路线,是因为此前的 TabbyAPI 测试让我对这个量化版本有了信心,而且使用它时,Maya 的解码速度可以达到 TabbyAPI 运行更小的 sc_2.60 量化版本时的水平。
GPU:RTX 5090,32 GB 显存,同时负责桌面显示。
CPU:Ryzen 9 9950X3D,16 核、32 线程。
内存:128 GB DDR5,4 根 32 GB,运行速率为 5,600 MT/s。
硬盘:一块 NVMe 硬盘。
操作系统:Arch Linux(Omarchy),NVIDIA 驱动 615.78,CUDA 13.4。
Maya 1.1.11,commit 为 d187195,日期为 2026 年 10 月 15 日。
git clone https://github.com/mw00/project-maya.git
cd project-maya
./maya.sh --check
--check 会输出 GPU、驱动、CUDA toolkit、编译器、内存和 CPU 信息。然后以非交互方式运行安装:
./maya.sh --setup --plain --yes --gpu 0 \
--context 131072 --model EXL3-3.05bpw \
--models-dir ~/Models/maya --download-model \
--no-vision --draft mtp --no-start
根据 Maya 的安装文档和我们的实际观察,安装过程会完成以下操作:
检查电脑,并将所需的 Python 包安装到 .venv。
获取固定 commit 的 llama.cpp 源码,并针对你的 GPU 编译引擎。Maya 文档给出的耗时为 10—30 分钟,只需执行一次。
下载 125.3 GB 的量化模型,共 27 个文件。它会先打印支持断点续传的 curl 命令,再执行下载,并逐个校验文件的 SHA-256。
在模型目录中构建 pack,也就是引擎用于索引模型文件的数据。在我们的机器上,生成了一个 1.3 GB 的 pack/ 目录,以及旁边一个 2 GB 的 maya-exl3.gguf 文件。
写入引擎配置文件 maya-exl3-3.05bpw.json,以及启动脚本 run-maya-exl3-3.05bpw.sh。
几个重要参数:
--model EXL3-3.05bpw 选择 turboderp 的 EXL3 量化版本,而不是 Maya 的 GGUF。
--draft mtp 使用模型自带的 MTP 模块草拟 token。另一个选项是 DFlash2 drafter,但它采用 CC BY-NC-ND 4.0 许可证,仅限非商业用途,所以我没有使用。
--no-vision 跳过图像编码器,省去 10—20 分钟的构建时间和 1.1 GB 空间。
--no-start 只安装、不启动,方便按下文的方式启动。
在 maya-exl3-3.05bpw.json 的 args 中加入两项设置:
"args": [
"--glm-pack", "/home/you/Models/maya/EXL3-3.05bpw/pack",
"--max-context", "524288",
"--expert-cache", "auto",
"--prefill", "auto",
"--kv-streaming", "on",
"--vram-reserve-mib", "3072"
]
--vram-reserve-mib 3072:指定 Maya 的专家池需要预留多少空闲显存。默认值是 700 MiB。我们的桌面也使用同一张显卡,显存占满时屏幕会闪烁,所以我们在所有配置中都预留了 3 GB。
--max-context 524288:GLM-5.3-Flash 最长支持 1M token,因此这里没有进行 RoPE 缩放,只是调大上限。启用 --kv-streaming on 后,增加上下文消耗的是内存,而不是显存。根据 Maya 保存到磁盘的会话大小估算,每个 token 大约需要 13 KB。
再次运行 --setup 会重新写入这个文件。Maya 文档说会保留显存预留量等设置,但最好还是备份一份。
Maya 会锁定大部分空闲内存,用于内存中的专家层。在这台机器上,它只留下约 4—5 GB 空闲内存。这会与 Linux 的两项默认设置发生冲突:
第一,shell 可能位于一个有内存限制的 systemd scope 中。我们的 Agent 终端 scope 的 memory.max 为 4 GiB,从这里启动的大进程会落入 swap。
第二,Omarchy 为用户的 app.slice 启用了 systemd-oomd。当一个 cgroup 的内存压力超过 50% 并持续 20 秒时,它就会将其杀掉。模型加载时锁定内存,恰好会触发这个条件。
因此,我们在一个独立的 slice 中启动它,不设置内存上限:
systemd-run --user --scope --collect --slice=llm.slice \
--unit="maya-$(date +%s)" -p MemoryMax=infinity \
./run-maya-exl3-3.05bpw.sh --plain
--plain 会以纯文本输出,代替 Maya 的全屏仪表盘,方便记录日志。停止时使用 systemctl --user stop 'maya-*.scope'。启动需要几分钟,之后执行:
curl -s http://127.0.0.1:8080/v1/models
curl -s http://127.0.0.1:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "glm-5.3-flash", "messages": [{"role": "user", "content": "Say hello in five words."}],
"max_tokens": 2000}'
仪表盘位于 http://127.0.0.1:8080/#monitor,可以查看解码速度、prefill 速度、显存命中率,以及专家分布在哪一层。让服务器继续监听 127.0.0.1;如果要开放给局域网,请同时使用 --host 0.0.0.0 和 --api-key。
Maya 的校准功能会测量 CPU 与 PCIe 链路之间如何分配工作,以及应该使用多少个 CPU 线程:
./maya.sh --calibrate --no-start
校准会加载完整模型,因此要先停止 Maya,并采用与服务器相同的方式运行:放在 llm.slice 中,不设置内存上限。为确保没有其他引擎加载在 GPU 上,只要 GPU 已使用的显存超过 1 GiB,校准就会拒绝运行。但同一张显卡上的桌面本身就占用了约 2 GB,因此校准在我们的机器上始终无法启动。我在本地修改了 maya.py 的 busy_gpus(),把阈值从 1024 MiB 提高到 3072 MiB。这是一个本地补丁:每次更新后都要检查,而且只有确定显卡上没有其他高负载任务时才应使用。
校准大约花了 10 分钟,Maya 预计的时间是 10—15 分钟。以下是我们机器上的完整输出:
the engine's own split (PCIe share 0.60): 23.7 tok/s
PCIe share 0.00: 21.1 tok/s
PCIe share 0.10: 24.6 tok/s
PCIe share 0.25: 23.9 tok/s
PCIe share 0.50: 24.1 tok/s
PCIe share 0.75: 23.3 tok/s
16 CPU threads: 24.6 tok/s
12 CPU threads: 21.9 tok/s
11 CPU threads: 20.0 tok/s
8 CPU threads: 18.1 tok/s
4 CPU threads: 13.7 tok/s
confirming against the engine's own settings ...
[ok] tuned for this PC: STRATA_GLM_PCIE_SHARE=0.10 (25.7 tok/s)
它会以环境变量的形式将结果存入配置。在参数扫描中,PCIe 分配比例为 0.10 时,比引擎默认分配方案快约 4%,即 24.6 对 23.7 tok/s;随后确认测试测得了 25.7 tok/s。CPU 线程少于 16 个时,性能会明显下降。
我们的测量方式是:使用客户端流式 benchmark 测试 OpenAI endpoint。每种设置运行八次,交替使用一个约 400 词的荷兰语散文 prompt 和一个编程 prompt(二分查找及其测试),采用贪心解码,输出 512 个 token,报告中位数。prefill 数据来自对应 prompt 长度下的大海捞针测试。每种长度使用的目标文本和填充文本都是固定的,而 Maya 会缓存 prompt 前缀,甚至写入磁盘、跨重启保留,所以后面的测试可能受益于前面的缓存:请将 prefill 数据视为近似值。测试期间,机器上没有运行其他高负载任务。
前两行使用默认的 700 MiB 显存预留量,可以看到显存峰值已经逼近这张 31.8 GiB 显卡的容量上限。将预留量调为 3 GB 后,峰值始终不超过 29.5 GiB。读取 506K token 花了 262 秒。512K 上下文下的解码速度与 262K 时一样快,因为 KV cache 会从内存流式传入。
与同一台机器上的 TabbyAPI 相比:在使用更大量化版本的情况下,解码速度与更小的 sc_2.60 量化版本基本相同;后者为 25.5 tok/s,来自 TabbyAPI 服务器日志,而非本次客户端 benchmark。与此同时,prefill 速度约为它的 1.7 倍,上下文长度则翻了一倍。
作为参考,Maya 的 README 列出了另一组数据:RTX 5090、Ryzen 9 7950X 和 96 GB DDR5,运行 Maya 自己的 Maya-M 量化版本,速度为“30+ tokens/s”。量化版本和 benchmark 都不同,因此不要把这些数字直接一一比较。
我们运行了此前测试 Qwen 配置时使用的那五项编程任务,均带隐藏测试:每项进行三次尝试,在沙箱中运行,reasoning effort 设为 medium,并使用各服务器默认的采样设置。Maya 为 temperature 1.0、top_p 0.95,Strata 使用贪心采样,TabbyAPI 为 temperature 0.7。
唯一一次失败发生在事件报告任务的一次尝试中:输出的 JSON 无效,多了一个尾随逗号。所有代码任务都通过了。这些任务太简单,无法据此判断哪个模型更聪明。它们能说明的是,桌面电脑上的 3-bit GLM 可以生成能正常工作的代码,但由于解码较慢,每项任务的耗时约为原来的 1.5 倍。
它运行时,旁边容不下其他高负载应用。Maya 会持续锁定内存,直到只剩约 4—5 GB 空闲,并占用 29—30 GB 显存。不要同时运行第二个模型运行时、游戏或 GPU 挖矿程序。切换模型,就意味着先停止一个,再启动另一个。
停止后,等显存释放。运行时停止后,显存需要几秒钟才会释放。过早启动下一个运行时,会导致显存检查失败,或分配到更小的专家池。
不稳定的内存会损坏下载文件。我们的四根 DIMM 在 6,000 MT/s EXPO 配置下并不稳定:出现过 kernel oops 和崩溃,在这期间写入磁盘的某个模型下载文件,大部分数据都已损坏。现在我们改用 5,600 MT/s。Maya 会使用 SHA-256 校验自己的下载文件;你自行下载的文件也应如此。
测量时使用新的 prompt。重复的长 prompt 会命中前缀缓存。我们有一次测试报告的“prefill”速度高达每秒 70,624 个 token,就是这个原因。
注意 reasoning effort 和采样设置。安装程序在配置中写入的服务器默认值是 "reasoning_effort": "high"、temperature 1.0 和 top_p 0.95。每秒只有 25 个 token 时,长推理的耗时会相当可观,因此交互使用时,可以考虑从客户端传入更低的 reasoning_effort。在 Qwen 配置上,medium 在我们自己的 benchmark 中得分最高;GLM 的情况我们还没有测过。
如今,在这一台机器上,我们有三种运行大模型的方式,通过停止脚本和启动脚本进行切换:
Qwen3.8-Flash-Next UD-Q5_K_XL,运行在 Strata 上:约每秒 79 个 token,512K 上下文,是我们日常编程和 Agent 工作的默认选择。
Qwen3.8-Flash-Next EXL3 4.05 bpw,运行在 TabbyAPI 上:服务器日志显示约每秒 68 个 token,上下文为 262K。
GLM-5.3-Flash EXL3 3.05 bpw,运行在 Maya 上:约每秒 25 个 token,321B 参数模型,512K 上下文,用于需要让第二个、更大的模型来审视问题的场景。
关于 Strata 配置、校准前后的 A/B 对比,以及我们自己的九项任务 benchmark,请参阅配套文章:《用 Strata 和 5-bit 量化,在 128 GB 内存上以 79 tok/s 运行 Qwen3.8-Flash-Next》。
如果你正在考虑购买什么硬件来本地运行 AI,Voltti 有一篇实用指南,介绍了企业使用本地 AI 与云端 AI 时的取舍。
如果还想采取进一步措施,可以考虑屏蔽此人和/或举报滥用行为。