首页 / 文章 / 10 年老 Xeon 搞定 Gemma-4:CPU 推理优化实战
← 返回
AI技术

10 年老 Xeon 搞定 Gemma-4:CPU 推理优化实战

✍️ zhirenhun 📅 2026/6/2 👁 102 阅读 ⏱ 27 分钟
10 年老 Xeon 搞定 Gemma-4:CPU 推理优化实战

发表于 2026年6月1日

阅读时间:17分钟

上一篇文章介绍了如何将 Gemma 4 的 MTP 草稿模型量化并与验证器配对。本文则要讲述如何让它在根本不配运行的硬件上跑起来。

我有一台回收来的服务器。优点是它有惊人的 128 GB 内存,但那是 DDR3……比当下最好的笔记本内存慢了 5-6 倍。它还有一颗 2016 年的英特尔至强 E5-2620 v4,比我笔记本的 CPU 慢大约 5 倍……

哦,我还提到了,我们没有 GPU。而且不,至强并没有集成显卡。

但是,请听我说……

如果我们直接在这里用 ollama,那么……正如之前的博客文章所说,我们做不到。而且如果六个月后他们为我们需要的模型添加了支持(如果他们真会加的话),那算我们走运。也可能永远都不会加。即便加了,ollama 也根本没暴露足够的旋钮让我们能把它跑好,甚至连标准的 llama-cpp 也是如此。

但,这就能阻止我们吗?

我收到反馈说前几篇文章太偏高层了,这次我会尽量把事说清楚。如果你是技术人员,或者是有装机经验并用过 ChatGPT 的 Linux 爱好者,那么大部分内容应该都能理解。

所以,先完全交代一下环境。硬件信息来自 lscpu: - CPU: Intel Xeon E5-2620 v4 @ 2.10 GHz - 核心: 8 物理核心,16 线程 - 指令集: AVX2(无 AVX-512、无 AVX-VNNI、无 BF16) - 缓存: 20 MiB L3,2 MiB L2 合计 - 内存: 128 GB DDR3 - GPU:

对于 LLM 推理来说,内存带宽是限制因素。每生成一个 token,都需要将数 GB 的权重从 RAM 搬运到 CPU 缓存。

当你使用 ChatGPT 这类工具并看着文字逐字显示在屏幕上时,你看到的就是“解码阶段”。在这个阶段,模型一次生成一部分(即一个“token”)输出。

在这一步中,系统的原始算力很少成为瓶颈。相反,限制因素是内存带宽。为了计算下一个词,处理器必须不断拉取大量数据。这些数据就是包含模型学习知识的“权重”。它们从内存移动到计算核心。

处理器执行所需的矩阵运算速度非常快,以至于它只能空闲等待,等着硬件将下一块权重通过内存总线物理搬运过来。用传统软件的术语来说,解码是严重内存受限的,而不是计算受限的。

这就是所谓的“内存墙”,是当前最大的性能障碍之一,无论你在至强上还是在 H100 上。

在没有 GPU 的 DDR3 机器上直接运行 llama-cli 会慢得离谱,即便它能跑,因为它是为通用 GPU 场景优化的,往往留下了很多改进空间。此外,它根本没有用到当前业界用来大规模运行这些模型的大部分实际优化。

补救方法是动用 ik_llama.cpp 暴露的所有优化杠杆。大部分都稍显晦涩。

下面是能让它真正跑起来的神奇咒语。

llama-cli 
  --model gemma-4-26B-A4B-it-Q8_0.gguf 
  --model-draft gemma-4-26B-A4B-it-assistant-GGUF/
wikitext-2-raw_ik-llama-mtp_drafter-conservative/
gemma-4-26B-A4B-it-assistant-Q8_0.gguf 
  --spec-type mtp --draft-max 3 --draft-p-min 0.0 --spec-autotune 
  -cnv --color --jinja --special 
  -sm graph -smgs -sas -mea 256 --split-mode-f32 
  --temp 0.7 -t 8 --parallel 8 
  --cpu-moe --merge-up-gate-experts 
  --flash-attn on --mla-use 3 
  --mlock --run-time-repack --no-kv-offload

ollama 这样的黑盒工具下你永远看不到这行命令。在老旧硬件上,你必须理解每个标志的作用,因为其中一半可能会失效,而引擎会顺带告诉你。

推测解码

--spec-type mtp --draft-max 3 --draft-p-min 0.0 --spec-autotune

这将 26B 验证器与上一篇文章中的小草稿模型配对。每次草稿最多生成三个 token(--draft-max 3),接受所有概率(--draft-p-min 0.0),--spec-autotune 根据工作负载自动调整链长度。

这直接联系到我们之前关于内存受限解码阶段的讨论。

当模型使用长推理链时,它会逐个生成那些“思考”token。即使内部推理对用户隐藏,你只看到一条简短答案,硬件仍然必须为隐藏链中的每个 token 执行一次完整的解码阶段。

事实上,推测解码是当前 AI 行业为了绕过“内存墙”而发明的最出色的软件变通方法之一,而 spec autotune 则是从中榨取最大速度的方法。

推测解码在 CPU 上的优势比在 GPU 上更强。相对于将验证器权重流经缓存的成本,CPU 算力很便宜,所以在一个活跃层容易塞进 L3 的小草稿模型上额外花费一些周期,就能以极低的边际成本换来 token。草稿模型的工作集适合 L3,而验证器则到处都是溢出。

CPU 与 MoE 路由

--cpu-moe --merge-up-gate-experts -t 8 --parallel 8

Gemma 4 26B-A4B 有 128 个专家,每个 token 激活 8 个,约 25.2B 总参数中约 3.8B 活跃参数。--cpu-moe 针对 CPU 缓存层次结构优化了路由。

CPU 处理内存的方式与 GPU 截然不同。GPU 拥有大量超快的高带宽内存(HBM),而 CPU 依赖的是直接内置于处理器芯片上的小型、极快的“缓存”(L1、L2、L3)。

在 MoE 模型中,在 128 个专家之间不断跳转会导致“缓存抖动”,CPU 不得不不断清空缓存,再从慢得多的主系统 RAM(通常是 DDR4/DDR5,而我们用的是 DDR3!)中获取新权重。

这个标志告诉路由器更智能地选择专家,优化顺序,使权重尽可能长时间地留在 CPU 本地缓存中。

--merge-up-gate-experts 将每个专家的两个投影融合成单个矩阵乘法,日志确认了这一点:

fused_up_gate = 1

这是一个绕过我们之前讨论的内存带宽瓶颈的软件技巧。

在专家内部,数学运算需要数据经过不同层。通常,处理器会计算“上投影”,将结果写回内存,然后加载“门投影”的权重,计算它,再合并。这需要多次经过内存总线搬运数据。

它不是分两次经过内存总线,而是将操作合并成一步。

-t 8 匹配物理核心数。这台机器有 16 个 SMT 线程,但只有 8 个核心。在内存受限的工作负载上,超量订阅线程只会增加调度开销,而不增加吞吐量:核心是在等待 DDR3,而不是在等待对方。

内存锁定、重打包、KV 缓存

--mlock --run-time-repack --no-kv-offload

--run-time-repack 在推理之前立即在内存中重新组织权重矩阵,以匹配 CPU 的缓存布局。日志确认了这一点:

============ Repacked 265 tensors

处理器有自己的超快内置内存,称为缓存(L1、L2、L3)。然而,这些缓存期望数据以特定的形状和大小输入。

如果 AI 的权重矩阵以通用布局存在于系统 RAM 中,CPU 就不得不尴尬地分块拉取数据,导致“缓存未命中”,CPU 停顿。--run-time-repack 告诉引擎在启动时花几秒钟在 RAM 中物理重新组织那些庞大的数字表格,使它们完美对齐 CPU 的摄取方式。它预先付出一点时间代价,以保证实际文本生成期间的最大内存带宽。

--mlock 用于将模型锁定在 RAM 中,防止操作系统将其任何部分交换到磁盘。

mlock 代表“内存锁定”,惊讶吧!在标准操作系统中,如果系统开始内存不足,它会悄悄将几秒钟未使用的数据“交换”(或分页)到物理硬盘上。

如果操作系统试图将 27 GB 的 AI 权重交换到磁盘,生成速度会立即降为零,同时系统苦苦挣扎尝试读回。--mlock 告诉 Linux 内核:“将这 27 GB 严格固定在物理 RAM 中。切勿将其移动到磁盘。”

请注意,如果不小心,你会看到:

warning: failed to mlock 27628376064-byte buffer
  (after previously locking 0 bytes): Cannot allocate memory
Try increasing RLIMIT_MEMLOCK ('ulimit -l' as root).

标志没问题;内核侧的 memlock 限制没有设得足够高来锁定 27 GB 缓冲区。这根本不是 LLM 特有的问题——这是 ulimit 默认值——也是黑盒工具通过从一开始就不要求这个优化而掩盖的那种暗坑。

想一想吧,许多工具默认情况下,如果它认为是最佳选择,就会毫不犹豫地将你的模型放入交换空间。你可以想象这对性能有多大伤害……

--no-kv-offload 告诉引擎不要为 KV 缓存寻找 GPU。根本找不到 GPU,但这个标志短路了检查。

KV(键值)缓存是 AI 的短期记忆——它存储当前对话的上下文,这样模型就不必为每个新 token 重新读取整个提示。

由于 KV 缓存不断被读写,AI 引擎通常试图将其“卸载”到 GPU 上,因为 GPU 的内存比我们的快得多。

由于这个特定设置高度优化为纯 CPU 运行,让引擎在硬件总线上搜索不存在的 GPU 是浪费时间的,并且可能抛出错误。这个标志显式地短路了那项检查,告诉引擎将短期记忆与权重一起放在系统 RAM 中。

图布局

我尽力让这部分容易理解,但这部分确实很难在一篇博客文章中解释清楚。

接下来是黑暗艺术。前沿 AI 软件的一个常见问题是引擎开发速度太快,以至于开发者没有时间编写官方文档。如果你想了解如何优化引擎,你必须深入原始代码或阅读开发者之间的 GitHub 拉取请求(PR)评论。

-sm graph -smgs -sas -mea 256 --split-mode-f32

这些标志控制计算图如何分配到内存区域。完整文档最终存在于代码中,尽管有一些文档。

标志 -sm graph 告诉引擎在图模式下使用分片模式(业界常称为张量并行)。这完全关于如何将庞大的数学工作负载分布到多个处理器或内存区域(例如多个 CPU 插槽或 GPU)。 - 层分片(默认/回退): 引擎水平切片模型。处理器 A 计算层 1-10,然后通过系统总线将数据发送给处理器 B,处理器 B 计算层 11-20。当处理器 A 工作时,处理器 B 空闲。 - 图分片(目标): 引擎垂直切片计算图。处理器 A 和处理器 B 同时计算层 1 的不同半部分,合并答案,然后一起移动到层 2。这使所有硬件同时 100% 运行,大幅提升生成速度。

在这次运行中,引擎拒绝了:

=======================================================
Split mode 'graph' is not supported for Gemma4 external MTP
  => changing split mode to 'layer'
=======================================================

因为 MTP 在网络末端创建了一个复杂得多的数学网络,这个推理引擎尚未获得支持来安全地“图分片”(垂直切片)一个 MTP 架构。当引擎启动时,它检测到 MTP 层,意识到 -sm graph 会破坏数学计算,于是安全地降级到较慢的顺序层分片,这样模型仍能运行。

我把它包括进来是因为将来它很可能非常有用,所以如果你使用更新版本,可以试试运气。

虽然 -sm graph 被禁用了,但其他标志仍然适用于引擎管理内存的方式: - -sas(跨插槽分片):显式告诉引擎如何在服务器主板上的不同物理 CPU 插槽(NUMA 节点)之间分配工作负载。你可能注意到我们只有一个 CPU,但以后可以增加,这是一个不错的优化,如果有旧主板可能会打破当前假设,所以如果要做的话,请务必测试以确保安全。 - --split-mode-f32:当数据跨处理器分片时,必须重新拼接回来。这个标志强制那些中间连接点使用 32 位浮点精度(更高质量的数学运算)。它防止 AI 因为分片过程中的舍入误差而失去智能或产生幻觉。

如果你看到下面这个也不用担心:

Oops: tensor with strange name rope_freqs.weight

它名字奇怪。奇怪的名字不会阻止我们。:D

注意力

看。ik_llama.cpp 的创建者 ikawrakow 已经超出了“厉害”这个词。

Kawrakow 编写了自定义 CPU 内核来处理 Flash Attention,从而在繁重的上下文处理过程中无需 GPU。

这让我们能够做一些通常只在 GPU 上才能做的事。

--flash-attn on --mla-use 3

Flash Attention 将注意力 softmax 与其矩阵乘法融合,以避免显式实现完整的注意力矩阵。当然,谁都知道这个,但我还是试着解释一下。

为了生成文本,AI 必须计算提示中每个单词与每个其他单词的关系。数学上,这会创建一个 N×N 的网格(N 是 token 数)。

如果你给 AI 一个短句,这个网格很小。但如果你给它一份 10 万词的文档,那个矩阵就会爆炸成 100 亿个单元格。通常,处理器会计算这个巨大的矩阵并“实现”它——即物理地将整个巨大网格写入主系统 RAM,然后立即读回用于下一步。

Flash Attention 应用了内核融合技巧,但用在注意力机制上。它分小块计算注意力分数,并融合数学运算(softmax),这样巨大的 N×N 矩阵永远不会实际写入 RAM。它完全在处理器的超快本地缓存内计算和消费。

Flash Attention 最初是严格为 GPU 发明的,因为它依赖于 GPU 硬件处理内存块的方式。成功地将这种高度复杂、硬件特定的优化移植到标准 CPU 上是一项巨大的软件工程成就。 干得好,ikawrakow。

--mla-use 3 启用多头潜在注意力。之前,我们讨论了 KV 缓存(AI 的短期记忆,防止它必须为每个单词重新读取整个提示)。

在标准架构中,为每个 token 存储原始的键和值数据会以惊人的速度消耗 RAM。多头潜在注意力(MLA)是一种突破性架构,它极大地压缩了这种短期记忆。它不为每个 token 保存原始数据,而是将键和值压缩成更小、更密集的数学表示(“潜在”空间)。

这极大地减少了 KV 缓存的内存占用,使模型能够记住大量对话而不会耗尽系统 RAM。标志 --mla-use 3 只是告诉引擎激活这种压缩的特定层级或内核实现。

但所有这些都只是实验性的东西,对吗?就像分片模式图一样?不是的。日志确认两者都已生效:

flash_attn  = 1
fused_moe  = 1
fused_up_gate = 1

来自日志的内存统计:

------------------- Layer sizes:
Layer  0:  825.98,  2048.00,  2873.98  77.00 MiB
...
Layer 29:  840.59,  1024.00,  1864.59  77.00 MiB
Layer 30:  748.00,  435.00,  1183.00  MiB (output layer)
--------------------------------------------------------------------------
Total  :  24852.46,  56755.00,  81607.46 MiB
Memory required for model tensors + cache: 82355 MiB

在 2016 年的至强上,DDR3 中的 82 GB 占用。约 25 GB 权重在完整 262K 上下文下加上 56 GB KV 缓存。KV 缓存比模型本身还大。

一个可工作的配置需要 25 个标志,其中一半没有文档记录,四分之一静默失败,这正好合理地定义了第一篇文章中描述的可用性护城河。

引擎加载了一个 25B 参数的 MoE,针对 MTP 草稿器运行推测解码,并在老旧硬件上以阅读速度生成文本——这硬件在该架构尚未发明时就已经过时了。

一周前我们开始这个系列时,本地开放权重 AI 的现状看起来黯淡。我们首先揭开了业界最喜欢的营销包装:将一个庞大、未经校准的权重文件放到仓库里就号称“开源”。我们看到了巨大的可用性护城河,它由缺失的文档、静默的默认设置以及以用户友好为名掩盖性能杀手决策的黑盒包装构成。

在第二篇文章中,我们挽起袖子,踏入泥泞。我们搜寻了晦涩的、未合并的拉取请求,编译了专门的 fork(ik_llama.cpp),把标准的量化逻辑颠倒过来,构建了高精度的推测解码草稿器,并编写了自定义脚本来清理 GGUF 元数据中的基础设施数据泄漏。

最后,在这篇文章中,我们兑现了承诺。我们把一台 2016 年的企业级遗物从柜子里拖了出来——不,是从坟墓里,一颗孤零零的英特尔至强,运行在慢得令人发指的 DDR3 RAM 上,完全没有 GPU——并强迫它以阅读速度运行一款尖端的、260 亿参数的混合专家架构。我们没有向问题砸异国硬件。相反,我们将部署管道视为正经事,将架构直接映射到物理硬件,调整内存分配,解锁 CPU 缓存优化的绝对极限。

这里的教训很简单:在本地运行最先进 AI 的瓶颈不仅仅在于硅片。它在于需要深入理解推理引擎实际如何工作。

虽然数据中心显卡集群、企业 API 令牌或巨额预算对特定工作负载极为有用,但对于开放模型覆盖的那些工作,你只需要翻新硬件并拒绝让黑盒工具掌握方向盘。有了正确的 fork、校准的量化以及对底层内存架构的理解,可用性护城河就消失了。

开放权重 AI 的前沿并非锁在付费墙或模型提供商后面。如果你已经在运行家庭实验室,它就在一台十年前的服务器命令行上。

欢迎来到护城河的另一边。现在去下载量化文件,动手干吧。

感谢阅读 :DCopy Codehttps://point.free/search_index.en.json$MATCHES more matches

——

🧑‍💻

zhirenhun

一个热爱技术的程序员,喜欢分享前沿AI知识和开发经验。

← 上一篇
Python Agent + DuckDB:71 行黑盒崩溃调试实战
下一篇 →
RGB 归一化该除以 255 还是 256?

📌 相关推荐

qMLX:通过极致优化Mac Studio最大化我的AI幻觉
2026/7/12
Mesh LLM:基于iroh的分布式AI计算
2026/7/12
结构化输出 vs 工具使用 vs 预填充:2026年从Claude获取JSON
2026/7/11
← 返回文章列表