Laya MLX 能快十倍吗?一次数学调查
研究日期:2026-09-19。基线:Apple M3 Max(40 个 GPU 核心、128 GiB 统一内存)上已提交的 FP16 MLX 结果。本报告区分代数事实、静态成本估计、选定 checkpoint 矩阵的 CPU 测量,以及需要推理实验的假设。这次数学调查没有运行任何 GPU 推理或新的延迟测量。配套的工程调查在有候选计时时会给出它们。这里的「精确」指保留数学依赖关系和实数算术函数;不同的 GPU 归约顺序或 kernel 仍可能改变浮点结果,所以现有的数值容差和已暴露输出的契约仍是验收门槛。
结论: 在保留这些 checkpoint 及其完整输出的前提下,不要为「靠手写 kernel 获得普遍的 10× 端到端改进」做预算。精确的局部注意力和输出裁剪是值得做但有界的改进。直接的秩分解在四个抽样的权重矩阵上远不算无损。对于一个有大量精确重复的工作负载,或者作为显著更小的蒸馏/重构模型的目标,10× 的产品改进是可信的。这些是不同的承诺,必须用不同的基准衡量。
1. 快十倍实际需要什么
下面是现有的同步、热态端到端中位数,包含准备和格式化;它们不是新的测量。每个基线使用五次预热、50 次计时迭代和 64 的问题批上限。一个短 50 问题固定样本重复三个问题定义;它的原始运行时仍会求值全部 50 个。下载、加载和编译时间在这些中位数之外。
| 模型 | 短 1:基线 → 10× 目标 | 短 10 | 短 50 | 长 1 | 长 10 |
|---|---|---|---|---|---|
| Laya | 13.421 → 1.342 ms | 71.068 → 7.107 ms | 336.030 → 33.603 ms | 44.927 → 4.493 ms | 420.987 → 42.099 ms |
| Multilingual | 7.390 → 0.739 ms | 27.386 → 2.739 ms | 127.565 → 12.756 ms | 37.635 → 3.763 ms | 389.487 → 38.949 ms |
| Typed decisions | 13.712 → 1.371 ms | 75.618 → 7.562 ms | 380.560 → 38.056 ms | 99.233 → 9.923 ms | 1000.294 → 100.029 ms |
来源:Laya FP16、multilingual FP16、typed-decisions FP16。短输入填充长度是 93/91/93;长长度是 512/1024/1024。比较它们的长行并没有保持 token 长度不变。目标是相对于原生 MLX FP16 的进一步改进,而不是相对于 PyTorch MPS FP32。
对任何提出的优化,设 f 为它实测占端到端真实时间的比例,s 为它自身的加速。Amdahl 定律给出:
whole-request speedup = 1 / (1 - f + f/s)
10× requires f > 0.9 and s >= f / (f - 0.9)
即使加速一个占据请求时间 95% 的热点,也需要 19× 的热点改进。在 98% 时仍需要 12.25×;99% 时需要 11×。任何未被触及、且至少消耗 10% 的准备、输出转换或同步,都会让仅靠其余部分无法获得有限的 10× 收益。独立的前向和端到端中位数不能相减来估计那个比例;要使用分段计时实验或剖析。
2. 稠密工作与条件下界
从 model.py 出发,定义隐藏宽度 D、编码器 MLP 宽度 I、编码器深度 N、头深度 H、批大小 B 和填充后的 token 长度 L。把一次乘法和一次加法计为两个 FLOPs:
A = N * (4 D² + 3 D I) + H * 12 D²
main dense FLOPs = 2 B L A
current dense attention products = 4 B (N + H) L² D
3DI 包含带门控编码器 MLP 的两个分支及其输出投影。头部的 MLP 使用一个不同的、常规的 4D 展开。这些公式排除归一化、激活、评分、掩码、传输和调度;它们是一个常规稠密实现的开销模型,不是对所有可能算法的无条件算术下界。
| 系列 | D / I / N / H | 主要稠密权重 A | 编码器 MLP 占 A 的比例 | A 的 FP16 字节数 |
|---|---|---|---|---|
| Laya / typed decisions | 1024 / 2624 / 28 / 2 | 368,312,320 | 61.28% | 736,624,640 |
| Multilingual | 768 / 1152 / 22 / 2 | 124,452,864 | 46.92% | 248,905,728 |
multilingual 嵌入有 196,608,000 个权重,但推理只收集选中的行,而不是与整个词表相乘。因此,总 checkpoint 参数量夸大了它相对于英文的逐 token 工作量。更小的嵌入文件不会自动带来更快的推理。
| 模型 / 形状 | 稠密 + 稠密注意力工作 | 10× 目标所需的有效吞吐 |
|---|---|---|
| Laya, B=1 L=93 | 69.57 GFLOPs | 51.84 TFLOP/s |
| Laya, B=50 L=93 | 3478.44 GFLOPs | 103.52 TFLOP/s |
| Laya, B=1 L=512 | 409.36 GFLOPs | 91.12 TFLOP/s |
| Multilingual, B=1 L=91 | 23.26 GFLOPs | 31.48 TFLOP/s |
| Multilingual, B=50 L=91 | 1163.05 GFLOPs | 91.17 TFLOP/s |
| Multilingual, B=1 L=1024 | 332.19 GFLOPs | 88.27 TFLOP/s |
| Typed decisions, B=1 L=1024 | 883.15 GFLOPs | 89.00 TFLOP/s |
这些是要求,不是声称的 Apple GPU 峰值。在这些形状上实测的稠密 GEMM 上限才是有用的工程比较。一个实测的上限可以让一个项目显得不可行;它仍然不是硬件上界的证明。由于 CPU 工作也落在目标之内,如果 CPU 工作不与 GPU 重叠,实际的 GPU 执行必须比这张表允许的更快完成。
Apple 为这个 40 核心的 M3 Max 配置标明 400 GB/s 的统一内存带宽。在「主要的 FP16 矩阵权重每次请求从统一内存读取一次、且尚未保留在片上缓存中」这一显式假设下,理想的流式下界是英文/typed 的 1.842 ms 和 multilingual 的 0.622 ms。这些忽略了激活、嵌入、评分器权重和全部计算。它们还假定标称的聚合带宽完全可用于这个工作负载。Apple 技术规格。
英文短单问题的目标 1.342/1.371 ms 已经低于那条常规的 FP16 流式下界。要在不改变权重存储的情况下于 400 GB/s 下满足这些目标,大约需要 200/188 MB 的计入权重避免内存读取,或者对执行假设做另一处更改。本报告不假定也不臆造任何片上缓存容量。跨批的权重复用、精确压缩和替代算法会改变这个下界;这一观察不是一个普遍的不可能性定理。
仅就稠密部分而言,理想的仅权重算术强度在 FP16 下是 BL FLOPs/byte:B=1 L=93 时为 93,B=50 时为 4650。激活流量会降低这些数字。这解释了为什么随着共享每个矩阵的 token 数量增加,权重压缩成为一种越来越没有说服力的吞吐策略。
3. 到底能移除多少精确工作?
第一个全局编码器层让每一个合法 token 都可能相关,而两个决策头层都是全局的。一个 token 不出现在最终输出里,并不意味着它的中间表示可以省掉:后续的 query 仍把它当作 key/value 使用。
精确的例外是最后一个头层。为所有合法 token 计算它的 K/V,只为 CLS 和选项标记计算 Q,并且只在那些选定位置计算它的输出投影/MLP。前一个头和完整的编码器仍必须产生所有合法 token 状态。这是依赖裁剪,不是移除注意力头。在包含 CLS 的 R=5 个选定位置下,当把 Q 从融合的 QKV 投影中拆出时,它的最大稠密节省是 20 B (L-R) D² FLOPs,外加 4 B L (L-R) D 的注意力 FLOPs。保留融合的 QKV 投影更简单,但节省更少。
局部编码器注意力允许 abs(q_position-k_position) <= 64,即一个包含端点的 129 位置内部窗口。L>64 时合法局部对的数量是 129L - 64*65。如果保留填充和位置,跳过被禁止的 K/V tile 在数学上是精确的。在稠密 QK 乘法之后施加掩码并不会实现那种算术节省。
| 模型 / 长度 | attention 乘积占建模 FLOPs 总量的比例 | 精确局部窗口节省 | 末头选择节省,R=5 | 合并节省 |
|---|---|---|---|---|
| Laya, 93 | 1.53% | 0.086% | 2.701% | 2.787% |
| Laya, 512 | 7.87% | 3.607% | 2.857% | 6.464% |
| Typed decisions, 1024 | 14.59% | 7.686% | 2.904% | 10.589% |
| Multilingual, 91 | 2.62% | 0.130% | 4.465% | 4.595% |
| Multilingual, 1024 | 23.27% | 11.919% | 4.584% | 16.503% |
这些是建模工作的削减,不是延迟预测。它们留下 83.5–97.2% 的建模工作不变,离 10% 的预算很远。即使让所有 attention 乘积免费,在这里也只移除 1.53–23.27%。反过来,在相同 FLOP 效率下,假想地把每一个稠密投影加速 10×、同时保持 attention 不变,对英文短输入只给出 8.79×,对 multilingual 长输入只给出 3.23×。在应用 Amdahl 之前,真实的剖析必须用实测的时间比例取代这些算术比例。
运行时已经调用 MLX 的快速 SDPA。FlashAttention 用更少的中间内存流量计算相同的稠密 softmax 注意力函数;它的分块并不会让任意的全局注意力在 token 数量上变成线性。利用 checkpoint 现有的局部掩码是精确的,而对它的全局层施加新的稀疏性会改变模型。QKᵀ 的低秩并不意味着逐元素指数化和行归一化之后仍然低秩。FlashAttention 论文、MLX 注意力 API。
在保持独立序列、原始位置和输出顺序的情况下,去填充也是精确的。当前的短 50 问题固定样本对英文/typed 只浪费 8.9%、对 multilingual 只浪费 5.8% 的填充 token。这些固定样本无法从移除填充中获得 10×。一个包含一个 1024 token 项和 49 个 64 token 项的不同工作负载会浪费足够多的填充,达到 12.3× 的 token 工作比;那会是一个特定于该分布的调度结果。
4. 低秩分解能揭示隐藏的 10× 捷径吗?
对一个形状为 m × n 的冻结矩阵 W,把它替换为两个因子 U(m × r) 和 V(r × n),会把逐 token 的乘法成本从 mn 变成 r(m+n)。盈亏平衡要求 r < mn/(m+n);10× 的矩阵工作削减要求:
r <= mn / (10(m+n))
best squared Frobenius residual at rank r = sum_{j>r} sigma_j²
第二个表达式是截断 SVD 的最优值。一个 1024 宽的正方形投影至多需要秩 51;它的精确满秩分解反而使乘法数量翻倍。GELU、门控、softmax 和依赖输入的 LayerNorm 使得无法简单地把相邻层的权重乘成一个常量矩阵。
我用一个 CPU float64 Gram 特征求解器检查了四个显式选定的中间层矩阵,每个模型系列各取一个注意力输出矩阵和一个融合 MLP 输入矩阵。最大的特征系统是 1024×1024;所有请求的 BLAS 线程上限都设为一,没有导入任何 GPU 库,也没有运行任何模型前向。这些是所选矩阵的完整谱,不是随机投影估计,也不是对每一层的普查。
| 样本矩阵 | 形状 | 10× 矩阵工作削减的最大秩 | 该秩下保留的平方 Frobenius 能量 | 最佳相对 Frobenius 误差 | 保留 99% 能量的秩 |
|---|---|---|---|---|---|
| Laya 第 14 层 attention Wo | 1024×1024 | 51 | 28.66% | 84.46% | 690 |
| Laya 第 14 层 MLP Wi | 5248×1024 | 85 | 29.29% | 84.09% | 956 |
| Multilingual 第 11 层 attention Wo | 768×768 | 38 | 24.97% | 86.62% | 516 |
| Multilingual 第 11 层 MLP Wi | 2304×768 | 57 | 32.88% | 81.93% | 697 |
原始测量、所选矩阵的 SHA-256、奇异值极值、稳定秩和额外的候选秩都在 math_spectrum.json 中。每个抽样矩阵在数值上都是满秩的。在四个当中,保留 99% 的平方 Frobenius 能量所需的秩都高于双因子算术的盈亏平衡点。multilingual 的 MLP Wi 稳定秩只有 13.29,然而秩 57 只保留总能量的 32.88%:稳定秩并不是实现小重建误差所需的维度。
这是反对把朴素的仅权重 SVD 当作近似无损捷径的有力证据。它并不证明每一个低秩模型的任务准确率都很差:token 激活可能占据一个受限的分布,而重训练可以把有用的计算移进一个更小的表示。激活感知的压缩应当最小化以实际输入协方差加权的误差,近似为 ||(W-Wr) Sigma_x^(1/2)||F,然后测试端到端质量。四矩阵分析没有估计那些协方差、全局的 logit 误差界,或全模型可达的加速。一个低秩微调增量也不意味着冻结的预训练矩阵本身可以被丢弃。
手写的快速矩阵乘法并不能推翻这个证据。作为一个算术示例,用七乘积的块递归代替八乘积,每一层只节省 12.5% 的乘法工作,还要加上额外的矩阵加法和流量;即使十个理想层也只产生约 3.8× 更少的乘法。把深递归应用到 768–1024 宽的投影上不是一个可信的 10× 延迟方案,尤其是面对已经分块的 GPU GEMM 时。这并不是声称所有可能的精确算法都已被排除。
5. 量化、裁剪和提前退出会改变契约
仅权重量化。 对组大小 64、带 FP16 scale 和 offset 的仿射组,每个矩阵参数的存储字节数约为 bits/8 + 4/64。相对于 FP16,这给出理想的矩阵存储削减:8-bit 时 1.88×、4-bit 时 3.56×、2-bit 时 6.40×。这些不是计算削减或真实时间收益。仅靠这个机制把权重流量降到十分之一,大约需要每个权重一个 bit 外加元数据,那是一种截然不同的近似。现有的 norm/embedding/head 张量和解码开销会进一步削减整个请求的收益。MLX quantize 文档、quantized matmul 文档。
如果权重流量占主导,量化在 B=1 时可能有用,但它不必加速一个大型 token GEMM。它会改变 logits、score 期望、熵置信度和动作概率。公开 API 暴露了所有这些,所以仅凭 argmax 一致是不够的。如果每个最终 logit 的变化至多为 epsilon,那么大于 2*epsilon 的 top-two logit 间距就能保证获胜标签,但不能保证概率、score 或动作一致。温度校准会用它的温度去除 logit 误差;一个很小的温度可能放大看似很小的原始误差。现有 checkpoint 含有接近 0.1006 的选项数量温度桶,这让这一点变得相关。
Token 裁剪。 在宽度/深度和稠密计算效率不变的情况下,一个近似的 10× 稠密工作目标需要跨层保留约 10% 的 token 处理,而不是去掉几个标点 token。在处理了原始深度的比例 a 之后裁剪,稠密工作比是 a + (1-a)rho,其中 rho 是后续层保留的 token 比例。如果 a >= 0.1,在那个简化模型里即使丢弃每一个剩余 token 也无法得到超过 10×。在这个模型里,第一个全局层已经把每个 state token 连接到所有未掩码的问题/选项 token。学习式的 token 重要性和动态裁剪可以研究,但它们的正确性是一个需要训练/校准的任务质量主张。被丢弃的 token 可能包含否定、罕见实体,或决定一个接近选项的事实;早期注意力低并不能证明它在后续层不相关。
提前退出。 简单地把第 3 层隐藏状态喂给一个在第 28 层之后训练的头,并不会保持它的输入分布。必须训练中间头和一条经过验证的置信度规则。一个 10× 均匀成本深度预算对英文约是 2.8 个编码器层、对 multilingual 约是 2.2 个,这还没算头和 CPU 开销。保留完整的当前头会让短序列的稠密预算更紧:仅它的两层就占英文/multilingual A 的 6.83%/11.37%。对 multilingual 来说,仅这个头就超过了整个 10% 的稠密工作预算。批内的分化也很重要:如果单个项仍留在一个未缩小的稠密批里,退出它们不会节省任何东西。FastBERT 和 DeeBERT 确立了带准确率/速度权衡的训练式自适应推理方法;它们报告的收益不是对 Laya 或这台 Mac 的测量。
一个近似的学生加教师回退方案,其期望归一化成本约为 c + q,其中 c 是学生成本除以教师成本,q 是教师回退率,假定串行执行。要达到 10×,需要 c + q <= 0.1:成本为教师 5% 的学生至多留下 5% 的请求用于回退。这可以改善平均延迟,而困难请求的 p95 仍接近教师延迟。基于置信度的路由不是一份精确等价性证明。
6. 究竟什么可以在问题之间复用?
提示是 [CLS] question/options [SEP] state [SEP];不同的问题可以同时改变 state 偏移和 state 截断。对第一层的 query i,注意力输出是:
o_i = sum_j exp(q_i dot k_j / sqrt(d)) v_j
/ sum_j exp(q_i dot k_j / sqrt(d))
改变任何未被掩码的问题 key/value,都会改变每一个 state query 的分子和分母。对有限的 logits 来说,在实数算术中未掩码的 softmax 权重为正。因此,第一个全局层之后的上下文 state 取决于问题。所有后续的 K/V 都取决于那些改变后的 state。所以在不同问题之间复用一个完整的 state 编码或解码器式 K/V 缓存会改变函数。共享原始文本是不够的;偏移、截断、掩码和标记元数据也有影响。
有一个值得区分的小的精确例外:在第一次注意力操作之前,归一化的 token 嵌入及其第一层、RoPE 之前的 Q/K/V 投影只取决于 token 身份。它们可以被缓存或预先计算,之后再施加绝对的 RoPE 位置。消除整个第一层 QKV 投影在英文/multilingual 里只移除主稠密工作的 0.85%/1.42%,还没算查表流量。如果把一个全词表的 QKV 表与普通嵌入一并保留,会增加约 309 MB/1.18 GB 的 FP16 存储。第一层的 state 到 state softmax 充分统计量也可以在相同的 state token/截断和相对位置条件下复用,然后通过稳定的 softmax 合并与问题贡献结合。这只节省一个注意力层的一部分;它不会让后续的上下文状态变得可复用。
精确的整输入去重有更大的潜力。如果 N 个请求的问题包含 U 个相同的已准备前向输入,就只求值 U 个,并把它们的原始输出映射回所有原始问题,同时带上正确的有序标签、校准、ID 和用量记账。相等性和缓存键必须覆盖所有已准备的张量,包括掩码、标记位置和问题类型;跨调用的键还必须标识 checkpoint revision、dtype 和执行配置。在现有的 50 问题固定样本里,U <= 3,所以理想的线性工作比是 50/3 = 16.67×。实际延迟更不可预测,因为小批的效率不同,而且准备/输出映射仍然存在。对 10 个问题和三个唯一输入,比例只有 3.33×。无论哪个结果,都必须配一个 50 个不同问题的基准。
用跨调用结果缓存时,平均归一化延迟是 1-h+h*epsilon,其中 h 是命中率,epsilon 是缓存命中成本除以未缓存推理成本。10× 的平均改进需要 h >= 0.9/(1-epsilon);如果一次命中花费推理的 1%,所需的命中率是 90.91%。要分别报告命中率、未命中、冷缓存延迟和未命中路径。标准基准反复调用完全相同的请求,所以一个未标注的跨调用缓存会很大程度上停止测量模型执行。
一个共享 state 编码器加问题特定的交叉注意力是一个有前景的重设计产品,但它需要重训练或蒸馏,因为它移除了原有的早期问题/state 交互。如果可复用的 state pass 成本大致等于一次旧的逐问题 pass,那么在 Q=50 时共享 pass 消耗旧总预算的 2%;为了 10× 目标,问题特定的工作至多再消耗另外 8%。在 Q=10 时,那一次共享 pass 在问题特定工作之前就已经用掉了 10%。state 长度、选项复杂度和所选的更小 state 编码器会改变这个估计。
7. 一条可信的、数量级模型改进路线
同时减少深度和宽度能提供足够的算术空间来吸收开销。下面是学生设计预算,不是已实现的模型、质量主张或实测加速。它们保留相同的 token 长度,使用一个带门控的编码器 MLP 和一个常规的决策头层,并按同样的 A 公式计数。
| 教师 | 候选 N / D / I / H | 主要稠密权重 | 教师/学生稠密工作比 |
|---|---|---|---|
| Laya / typed | 6 / 512 / 1344 / 1 | 21.82 M | 16.88× |
| Laya / typed | 4 / 512 / 1344 / 1 | 15.60 M | 23.61× |
| Multilingual | 6 / 384 / 576 / 1 | 9.29 M | 13.40× |
| Multilingual | 4 / 384 / 576 / 1 | 6.78 M | 18.35× |
嵌入可以保持相对较大,而收集它仍然便宜。蒸馏教师的选项分布和动作输出,混入带标签的任务,覆盖 score/noul 行为和不同的选项数量,然后在留出数据上重新拟合输出校准。评估完整的语言覆盖和不同的问句。TinyBERT 是证据,表明通过蒸馏同时减少编码器深度/宽度可以在另一种 BERT 设置中带来重大的速度/质量权衡;它报告的 9.4× 推理增益不能按数值迁移到 Laya。
对于手写工程,优先考虑以下决策:
- 在写新的 GEMM 之前先确定上限。 在 B=1 和一个吞吐批下测量已编译模型的时间和代表性的稠密原语。把实际持续吞吐与上面的 31–104 TFLOP/s 要求比较。如果移除 launch 之后稠密执行仍占主导,新的逐元素 kernel 无法补上缺失的那个数量级。
- 把精确的输出选择和精确的局部注意力作为有界项目来实现。 最后一个头有清晰的依赖证明;multilingual 的长输入局部路径有最大的精确算术机会。在维护自定义 Metal 之前检查实测的真实时间比例。保留现有快速注意力的数值契约,并测试边界长度/填充。
- 只有在做了工作负载记账之后才发布精确去重。 对于一个足够重复的应用,这是通往可能的 10× 结果最快的路径。它必须与不缓存、唯一输入的基准共存,这样用户才能预测自己的结果。
- 把 4/8-bit 和激活感知的低秩当作经过测量的近似。 同时要求速度改进和经过校准的质量门槛。无论是更少的存储字节还是一个低的稳定秩数字,都不充分。
- 如果对全新的、多样的请求需要 10×,就开发并验证更小的学生或共享 state 架构。 学生预算刻意瞄准超过 10× 的稠密工作削减,因为 attention、CPU 准备和小 kernel 开销仍然存在。一个质量预算和合适的训练/评估数据是前提;现有的保真固定样本无法验证这个主张。
对近似变体,验收应当记录 choice 一致和带标签的准确率、score 误差、概率漂移、置信度校准、动作概率和接近间距的情形。现有的 378/378 argmax 检查、600 次有限重复调用和 AG News 回归对齐确立了当前端口在那些测试上的行为;它们并不能验证一个新的压缩模型。保留一个独立的模型身份,并把 p50/p95、冷启动设置、内存、唯一输入数量和质量一并报告。
复现与范围
- math_costs.py 从 checkpoint 配置和现有基准 JSON 复现每一张由架构推导的表和延迟目标;math_costs.json 记录输入文件的哈希和 checkpoint revision。
- math_spectrum.py 复现四个选定的 CPU 矩阵谱;math_spectrum.json 包含精确的矩阵哈希。它只用 NumPy 和 safetensors,不加载完整模型。
- 下载锁定版本的源 checkpoint 后,在仓库根目录运行
.venv/bin/python experiments/math_costs.py和.venv/bin/python experiments/math_spectrum.py。CPU 采样与工程 GPU 计时经过协调以避免重叠。 - 当前 MLX 量化语义用
find-docsskill 核对,先做规定的 Context7 库解析,再做一次单独的量化文档查询。来源包括官方 MLX 文档、ModernBERT/FlashAttention 和蒸馏/提前退出论文、Apple 规格,以及实际的本地模型。论文里的任何性能数字都没有被作为这台机器上的测量来呈现。
中文结论: 相同 checkpoint、相同完整输出语义下,暂时没有可信的“手写几个 kernel 就再快 10×”路径。现有模型的大头是 dense 计算;局部 attention 加最后 head 精确裁剪只减少约 2.8%–16.5% 的建模 FLOPs。真实权重抽样显示,把矩阵分解压到十分之一工作量会产生约 82%–87% 的最佳相对 Frobenius 重建误差,不能当成近似无损捷径。10× 更有希望来自高重复输入的精确去重/缓存,或通过蒸馏把层数与宽度一起缩小、重新设计共享 state 的编码方式。前者需要公布命中率与独立输入性能,后者需要训练和重新验证准确率、分数、概率及 action 行为。