---
title: "oQ 量化：在 Mac 上把大模型装进更小的内存"
description: "从 MLX、mlx-lm 和 oMLX 的关系讲起，解释 oQ 如何用校准数据测量层敏感度，再用混合精度分配模型的量化预算。"
date: "2026-08-21"
type: "notes"
kind: "note"
tags:
  - 大模型
  - 量化
  - Mac
  - MLX
  - oMLX
series: "local-llm"
draft: false
---

在 Mac 上运行大模型，最先撞上的限制通常是内存。Apple Silicon 把 CPU 和 GPU 放进统一内存架构里，模型权重、运行时缓存和系统进程会共同占用这块空间。模型参数使用的数值精度越高，权重文件越大，装载和推理的压力也越高。

量化就是在这里发挥作用。它把权重从较高精度转换为较低精度，用更少的位数表示相近的数值。代价是会产生误差，收益是模型更小，内存占用更低，在支持对应内核的情况下也可能获得更高的推理速度。

## 先把 MLX、mlx-lm 和 oMLX 分开

这几个名字经常一起出现，职责却不同。

**MLX** 是 Apple 为 Apple Silicon 设计的机器学习框架。它提供数组、自动微分、神经网络模块和面向 Apple GPU 的计算能力。

**mlx-lm** 是建立在 MLX 之上的语言模型工具链，负责模型转换、量化、推理和微调。一个模型能否作为 MLX 模型运行，通常要先经过这套工具链的格式转换或适配。

**oMLX** 是面向 Mac 本地推理的服务和管理系统。它可以加载 MLX 模型，处理模型切换、缓存、并发和推理配置。oQ 属于 oMLX 项目提供的量化方案，但输出仍然遵循 MLX 生态能够识别的模型格式。

因此，oQ 量化后的模型并不只对 oMLX 有效。oMLX 官方文档明确把 oQ 的目标写成生成标准的 mlx-lm 兼容模型，其他支持 MLX safetensors 的应用也可能直接加载它。能否加载，还要看应用对模型架构和配置的支持程度。

## 普通量化为什么会损失质量

最简单的量化方法会给一组权重规定相同的位数和相同的分组方式。以 4 bit 为例，一组浮点权重会被压缩成更少的离散数值，再配合 scale 和 bias 在推理时近似恢复。

问题在于，模型里的不同参数对输出的影响并不一样。有些层的权重稍微变动，最终输出就会明显变化。有些层对误差更宽容。如果所有张量都用同一套精度，预算会花在不需要保护的地方，敏感部分也可能被压得太低。

传统的“全模型统一 4 bit”容易理解，执行也简单，但它把一个和数据有关的问题处理成了固定规则。oQ 试图把这个决定交回校准数据。

## oQ 把测量敏感度放在前面

oQ 的全称是 **oMLX Universal Dynamic Quantization**。它是一套面向 Apple Silicon 的数据驱动混合精度量化方案。

它的基本流程可以拆成三步。

第一步是校准。量化器使用一组内置校准样本让模型运行，比较浮点输出与量化输出之间的误差。oMLX 当前的官方文档写明，内置数据集包含代码、英文、中文、日文、韩文、工具调用和推理等类别，共 600 个样本。

第二步是制定预算。量化器根据不同层的敏感度决定哪些张量需要提升精度，再把总的平均 bits per weight，也就是 bpw，控制在目标范围内。oQ4 的基础位数是 4，官方文档给出的目标 bpw 约为 4.6，这个数字高于 4，正是因为部分张量获得了额外位数。

第三步是写出模型。普通权重按照计划量化，敏感层和受保护张量保留更高精度，最后保存成 MLX safetensors 模型。

这里的“混合精度”不等于简单地给注意力层 8 bit、给前馈层 4 bit。oQ 会结合实际测得的层敏感度、模型结构、张量位置和预算规则做决定。不同模型得到的分配计划也可能不同。

## 哪些东西会被保护

oQ 的官方文档列出了一些强制保护规则。常见例子包括 `lm_head`、MoE 路由器和共享专家门控。视觉编码器通常保留 fp16，某些 SSM 状态参数则需要 fp32。

这些规则有明确的工程原因。`lm_head` 直接参与从隐藏状态到词表概率的映射，MoE 路由器决定 token 进入哪个专家。它们的误差会放大到后续决策里。保护这些小而关键的组件，往往比把所有张量都升到高精度划算。

MoE 模型还带来一个额外问题。专家参数可能占模型总参数的大部分，但每个 token 只会激活其中一小部分。oQ 的预算分配会把参数规模和质量收益一起考虑，不能只看某一层的局部误差。

## oQ、oQ+ 和 oQe 怎么区分

这几个名字属于不同的量化路径，不能只按数字大小理解。

### oQ Streaming

Streaming 路径使用内存映射方式逐个读取 safetensors 张量，测量敏感度，制定预算，再把结果分片写出。它不要求完整模型始终驻留内存，适合大模型转换，也更适合统一内存有限的 Mac。

它的主要价值是转换过程的内存控制。对于很大的 checkpoint，oMLX 会根据当前可用内存和 Metal 工作集限制选择代理模型或缩小校准批次。这里解决的是量化过程能否跑完的问题，不代表最终模型一定适合在任意 Mac 上推理。

### oQ+

oQ+ 在敏感度测量和混合精度预算之后增加 GPTQ 权重优化。标准量化通常把权重取整到最近的量化网格，GPTQ 会利用校准输入构造的 Hessian 信息，在一个权重的取整产生误差后调整其他权重，尽量补偿这部分误差。

oQ+ 的输出格式和推理阶段的基本结构保持一致，额外成本主要发生在转换阶段。对于 MoE，oMLX 文档还介绍了批量处理专家权重的做法，让多个专家共享输入产生的 Hessian 信息，减少逐个处理的时间。

### oQe

oQe 的 `e` 可以理解为 enhanced。它在 oQ 的敏感度计划之外，引入 imatrix，也就是重要性矩阵。量化器会从代表性输入的激活中收集通道重要性，再让量化误差更多地落在影响较小的通道上。

这和 llama.cpp 生态里的 imatrix 思路相近，但实现细节取决于具体项目和版本。对于 MoE，重要性统计还需要注意专家覆盖，某些专家如果没有被校准数据激活，得到的矩阵就不足以支撑可靠的判断。

oQe 的名称和可用入口会随 oMLX 版本变化。社区曾出现过增强量化路径重构和暂时关闭界面的讨论，因此下载模型或准备自己转换时，应该同时查看 oMLX 版本、发布说明和模型卡。不能只看文件名里的 `oQ4e` 就推断所有运行时都支持同样的行为。

## oQ 的量化等级怎么理解

官方文档给出的等级大致如下。

| 等级 | 基础位数 | 目标 bpw | 适合的理解 |
| --- | --- | --- | --- |
| oQ2 | 2 | 约 2.9 | 尽量压缩体积，质量风险较高 |
| oQ3 | 3 | 约 3.5 | 在内存压力下保留基本能力 |
| oQ4 | 4 | 约 4.6 | 默认优先尝试的平衡点 |
| oQ5 | 5 | 约 5.5 | 用更大体积换取更高质量 |
| oQ6 | 6 | 约 6.5 | 接近无损的高质量方向 |
| oQ8 | 8 | 约 8.6 | 更接近原始精度 |

这里的 bpw 不能直接等同于文件大小。模型结构、未量化张量、scale 和 bias、分片格式都会影响最终大小。选择量化等级时，先看模型是否能装下，再看任务质量是否够用。

## oQ 和 DFlash、MTP 是什么关系

这三个名字解决的不是同一个问题。

oQ 处理模型权重。它通过降低并重新分配权重精度，减少模型体积和内存压力。

DFlash 和 MTP 处理生成过程。它们属于推测解码思路，先预测多个候选 token，再由目标模型验证。DFlash 需要额外的草稿模型，MTP 使用模型自身的多 token 预测头。oMLX 的模型设置代码明确把原生 MTP 与 DFlash 标记为互斥的推测路径。

因此，oQ 可以和 DFlash 或 MTP 形成组合，但组合关系要分层理解。oQ 让模型更小，DFlash 或 MTP 尝试减少生成阶段的目标模型调用次数。量化降低的是内存和计算压力，推测解码提高的是每轮验证带来的有效 token 数，两者可能互相帮助，却不能相互替代。

## 官方 benchmark 应该怎样读

oMLX 的 oQ 文档给出过 Qwen3.5-35B-A3B 的对比数据。在 4 bit 一栏，MMLU 的 mlx-lm 结果是 79.7%，oQ 是 83.3%；HumanEval 的 mlx-lm 结果是 87.2%，oQ 是 85.4%。这组数据说明混合精度在某些任务上有收益，也说明它并非每个指标都更高。

它不是对所有模型、所有任务和所有硬件的保证。benchmark 样本数、模型版本、提示模板、推理参数和评测脚本都会改变结果。实际选型仍然需要用自己的任务集测试，尤其是代码生成、中文长文本、工具调用和 MoE 模型。

## 在 Mac 上如何选择

如果只是第一次尝试，可以从模型作者明确提供的 oQ4 或 oQ4e 版本开始。oQ4 通常是体积和质量之间较稳妥的起点，oQ5 和 oQ6 适合内存充足且更在意质量的人。oQ2 和 oQ3 适合内存紧张的场景，使用前要接受更明显的能力损失风险。

如果你准备自己量化，先确认三件事。

- 源模型的架构是否被当前 oMLX、mlx-lm 或 mlx-vlm 支持。
- 量化时的可用统一内存是否足够，是否需要 Streaming 路径或代理模型。
- 量化后要运行的应用是否支持对应的 MLX safetensors 配置。

不要把“能下载”当成“能稳定运行”。模型文件、推理后端、上下文长度、KV cache、并发数和 Mac 的统一内存会一起决定最后的体验。

## 小结

oQ 的价值不只在于把模型从 16 bit 压到 4 bit。它把量化看成一个需要测量的分配问题，先观察哪些层怕误差，再把有限的位数花在更值得保护的地方。

在 MLX 生态里，MLX 提供计算框架，mlx-lm 负责模型工具链，oMLX 提供本地推理系统，oQ 负责其中的模型压缩路径。理解这条关系以后，oQ、oQ+、oQe、DFlash 和 MTP 就不再是一串混在一起的版本号，而是分别位于模型表示、量化优化和生成加速的不同位置。

## 参考资料

- [oMLX 官方 oQ 量化文档](https://github.com/jundot/omlx/blob/main/docs/oQ_Quantization.md)
- [oMLX 项目仓库](https://github.com/jundot/omlx)
- [MLX 项目仓库](https://github.com/ml-explore/mlx)
- [mlx-lm 项目仓库](https://github.com/ml-explore/mlx-lm)
- [Apple Developer 关于 MLX 和量化的介绍](https://developer.apple.com/videos/play/wwdc2025/315/)
- [oMLX 模型设置中的 DFlash 与 MTP 约束](https://github.com/jundot/omlx/blob/main/omlx/model_settings.py)
- [oMLX v0.5.0 发布说明](https://github.com/jundot/omlx/releases/tag/v0.5.0)
- [Hacker News 上关于本地模型和量化的讨论](https://news.ycombinator.com/)
- [Reddit 上 oQ 的项目介绍](https://www.reddit.com/r/oMLX/comments/1s1uf43/introducing_oq_datadriven_mixedprecision/)
