要让全球 95% 的联网人口都能在 50 毫秒内获得推理响应,就必须对 GPU 显存精打细算。去年,我们通过基于 Rust 的推理引擎 Infire 提升了显存利用率,又借助模型调度平台 Omni 消除了冷启动。现在,我们要攻克推理平台的下一个大瓶颈:模型权重。
LLM 每生成一个 token,都需要从 GPU 显存中读取全部模型权重。在我们许多数据中心使用的 NVIDIA H100 GPU 上,张量核心处理数据的速度比显存供数据的速度快近 600 倍,瓶颈因此不在计算,而在显存带宽。凡是经过内存总线的每一个字节,只要权重更小,本来都是可以省下的。
为解决这个问题,我们构建了 Unweight:一套无损压缩系统,可将模型权重缩小最多 15–22%,同时保证输出逐位精确一致,且不依赖任何特殊硬件。其核心突破在于:在快速的片上内存中解压权重,并直接送入张量核心,从而避免了一次经由慢速主存的往返。根据工作负载的不同,Unweight 的运行时会从多种执行策略中选择,有的策略以简单为先,有的则尽量减少内存流量,再由自动调优器为每个权重矩阵和每种批大小挑出最优方案。
本文将深入介绍 Unweight 的工作原理。同时,本着提高透明度、鼓励这一快速发展领域创新的精神,我们也发布了一篇技术论文,并开源了GPU 内核。
在 Llama-3.1-8B 上的初步结果显示,仅多层感知机(Multi-Layer Perceptron,MLP)权重就实现了约 30% 的压缩。由于 Unweight 只对用于解码的参数有选择地进行处理,模型体积因此缩小 15–22%,并节省约 3 GB 显存。如下图所示,这让我们能从 GPU 中榨取更多价值,在更多地方运行更多模型,使 Cloudflare 网络上的推理更便宜、更快。

有了 Unweight,我们可以在单块 GPU 上容纳更多模型
为什么压缩比听起来更难
目前有越来越多的研究在探索如何用各种巧妙的方式压缩模型权重,以加速推理,或让模型能在更小的 GPU 上运行。最常见的是量化,即把庞大的 32 位或 16 位浮点数转换为更小的 8 位或 4 位整数,以缩小模型权重和激活值的体积。这是一种有损压缩:不同的 16 位浮点值可能被转换成同一个 4 位整数。这种精度损失会以不可预测的方式影响回答质量。对于要服务多样化场景的生产级推理,我们明确希望采用能保持模型行为完全一致的无损方案。
最近有几个系统(Huff-LLM、ZipNN 和 ZipServ)已经证明 LLM 权重可以被大幅压缩,但它们针对的问题与我们不同。ZipNN 压缩权重用于分发和存储,解压在 CPU 上进行。Huff-LLM 提出使用定制的 FPGA 硬件来解码。ZipServ 确实把解压与 GPU 推理融合在了一起,但面向的是消费级 GPU,无法适配我们的 H100 GPU。它们都没能满足我们的需求:在 Hopper GPU 上实现无损的推理时解压,并能与我们基于 Rust 的推理引擎集成。
核心挑战并不在于常规意义上的压缩:BF16 权重中的指数字节高度冗余,熵编码对它们很有效。真正的挑战是解压要足够快,不能拖慢推理。在 H100 上,张量核心大部分时间都闲置着等待内存,但这部分空闲算力并不能简单地挪去做解压。由于共享内存的限制,每个 GPU 计算单元要么运行解压内核,要么运行矩阵乘法内核,不能同时运行两者。任何没有与矩阵乘法完美重叠的解码延迟,都会直接叠加到 token 延迟上。Unweight 的解法是在快速的片上共享内存中解压权重,并把结果直接送入张量核心,但要让这套做法在不同的批大小和权重形状下都高效运转,才是真正的工程难点所在。
如何有效压缩模型权重
AI 模型中的每个数字都以 16 位“脑浮点数”(brain float,BF16)存储。每个 BF16 值由三部分组成:
- 符号位(1 位):正或负
- 指数(8 位):数量级
- 尾数(7 位):该数量级内的精确值
下面展示其中一个权重是如何拆解的:

符号位和尾数在各个权重之间的变化不可预测,看上去就像随机数据,无法做有意义的压缩。但指数的情况则完全不同。
指数出人意料地可预测
已有研究证实,在训练好的 LLM 中,256 个可能的指数值里只有寥寥几个占主导地位。在典型的一层中,最常见的 16 个指数覆盖了超过 99% 的权重。信息论告诉我们,表示这种分布只需约 2.6 位,远低于分配的 8 位。观察典型 LLM 层的指数值分布就能看到,前 16 个指数占了全部模型权重的 99%。
典型 LLM 层中的指数值分布

Unweight 利用的正是这种冗余。我们保持符号位和尾数不动,只用霍夫曼编码压缩指数字节。这是一种经典技术,为常见值分配短码,为罕见值分配长码。由于指数分布极度偏斜,指数流因此获得了约 30% 的压缩率。我们有选择地将其应用于 MLP 权重矩阵(gate、up 和 down 投影),它们约占模型参数的三分之二,也主导着生成 token 时的内存流量。注意力权重、嵌入和层归一化则不压缩。综合来看,这些优化使多层感知机(MLP)权重的总体大小缩减约 20%,详细说明见我们的技术报告。
少数带有罕见指数的权重会被单独处理:如果一行 64 个权重中有任何一个的指数落在前 16 项调色板之外,整行就按原样存储。这种做法消除了热点路径上逐元素的分支判断:我们不必逐个检查每个权重是否属于边界情况,而是预先对每一行做一次决定。
GPU 显存瓶颈
NVIDIA H100 GPU 有两类相关的内存:
- 高带宽内存(High Bandwidth Memory,HBM):容量大,但访问相对较慢。模型权重就存放在这里。
- 共享内存(Shared Memory,SMEM):容量很小,但速度极快。GPU 在做数学运算之前,会先把数据暂存在这里。

推理时,生成每个 token 都需要从 HBM 读取完整的权重矩阵。HBM 与 SMEM 之间的内存总线是性能瓶颈,而不是数学运算本身。穿过总线的字节越少,token 生成就越快。
推理时,生成每个 token 都需要通过内存总线从 HBM 读取完整的权重矩阵,这就是瓶颈所在。H100 张量核心处理数字的速度远快于 HBM 向它们供数据的速度。压缩之所以有帮助,是因为需要穿过总线的字节变少了。但有一个问题:GPU 无法直接对压缩数据做运算,必须先解压权重。
以往的大多数工作会把整个权重矩阵解压回 HBM,再运行标准的矩阵乘法。这有助于节省存储容量,却无助于带宽,因为每生成一个 token,你仍然要从 HBM 读取完整的未压缩矩阵。
使用压缩权重的四种方式
推理时使用压缩权重并没有唯一最优的方式。合适的做法取决于工作负载,包括批大小、权重矩阵的形状,以及有多少 GPU 时间可用于解压。Unweight 提供四条压缩执行流水线,在解压开销与计算复杂度之间各有不同的取舍:完整霍夫曼解码、仅指数解码、调色板转码,或完全跳过预处理。

四种不同的执行流水线
这四条流水线构成了一个连续谱。一端是完整解码,它完全重建原始的 BF16 权重,并交给 NVIDIA 的 cuBLAS 库做标准矩阵乘法。这是最简单的路径,cuBLAS 在普通数据上全速运行,但预处理步骤写回主存的字节最多。它在小批量下表现良好,因为此时矩阵乘法很小,自定义内核的开销占主导。另一端是直接调色板,它完全跳过预处理。权重在模型加载时就被预先转码为紧凑的 4 位格式,矩阵乘法内核则根据这些索引即时重建 BF16 值。预处理成本为零,但内核对每个元素要做更多工作。
中间是两条相互独立的路径:一条只解码指数字节(预处理流量减半),另一条在运行时转码为 4 位调色板索引(流量降至四分之一)。两者都使用重建式矩阵乘法,这是一种自定义内核:它加载压缩数据,在快速的共享内存中重建 BF16,并直接送入张量核心,无需往返主存。
为什么没有哪条流水线能通吃
预处理越少,写入 HBM 的数据就越少,内存总线也就越早腾出来。但这会把更多的重建工作转移到矩阵乘法内核上。这种取舍是否划算,要看具体情况。
在批大小较小时(即 1–64 个 token),矩阵乘法很小,没有多少计算可供重叠,自定义内核的固定开销占主导。完整解码加 cuBLAS 往往胜出,仅仅因为 cuBLAS 的开销更低。在批大小较大时(即 256 个以上 token),矩阵乘法运行得足够久,可以吸收额外的重建工作。更轻量的预处理完成得更快,腾出的总线带宽和计算重叠就会带来收益,调色板或指数流水线随之领先。同一层内不同的权重矩阵也可能偏好不同的流水线。“gate”和“up”投影的维度与“down”投影不同,会改变矩阵乘法内部的运算顺序,因而需要不同的性能取舍。
吞吐量与流水线策略的关系

这就是 Unweight 不硬编码单一策略的原因。运行时会针对每个批大小,为每个权重矩阵挑选最佳流水线,依据是一个自动调优过程,它在目标硬件上测量实际的端到端吞吐量(下文详述)。
重建式矩阵乘法如何工作
四条流水线中有三条使用自定义矩阵乘法内核,将解压与计算融合在一起。该内核从 HBM 加载压缩数据,在共享内存中重建原始 BF16 值,并直接送入张量核心,全部在一次操作中完成。重建出的权重从不会出现在主存中。
传统解压与 Unweight 的对比

使用 Unweight 后,MLP 权重矩阵穿过内存总线的字节数减少约 30%
在这个内核内部,GPU 的线程组被分为两种角色:
- 生产者组使用专用的内存拷贝硬件(TMA)把压缩输入从 HBM 加载到共享内存中。它暂存符号位加尾数字节、指数数据(或调色板索引),以及对于带有罕见指数的行,按原样存储的指数行。它跑在消费者前面,填充一个环形缓冲区,使数据在被需要之前就已就绪。
- 消费者组把指数与符号位加尾数字节组合起来重建 BF16 值,然后立即将结果送入 Hopper 的 WGMMA 张量核心指令。重建出的权重直接从拼装进入计算,不离开共享内存。
重建式矩阵乘法有多种变体,区别在于每个计算单元处理多少个输出分块,以及环形缓冲区有多深。更宽的输出分块可在大批量下提高数据复用;更深的缓冲区则能在小批量下隐藏内存延迟。自动调优器会针对每种工作负载选出最佳变体。
在解码与计算之间共享 GPU
在两条融合流水线中,一个独立的预处理内核(霍夫曼解码器或调色板转码器)与重建式矩阵乘法并发运行。但这些内核会争夺 GPU 资源。
在 Hopper 上,每个计算单元(SM)有 228 KB 共享内存。重建式矩阵乘法的流水线缓冲区和累加器分块需要约 227 KB。解码内核的霍夫曼查找表需要约 16 KB。由于 227 + 16 > 228,这两个内核无法共用同一个计算单元。每分配一个 SM 去做解码,矩阵乘法就少一个可用的 SM。

这就形成了一种平衡:分给解码的 SM 越多,预处理越快,但矩阵乘法越慢,反之亦然。最佳的划分比例是另一个可调参数,也是自动调优器要测量真实吞吐量、而不是依赖启发式规则的又一个原因。
跨层流水线
即便存在 SM 划分的限制,Unweight 仍然利用 Transformer 模型的结构隐藏了大部分解压开销。
并非每一层在运行时都需要霍夫曼解码。Unweight 把各层分为“困难”(需要霍夫曼预处理)和“容易”(使用预先转码的调色板数据,矩阵乘法可直接消费)两类。运行时在两者之间交替:

在引导阶段、注意力计算和容易层的 MLP 计算期间,解码在独立的 CUDA 流上运行。等到困难层的 MLP 开始运行时,它预处理好的权重已经在等着了
当 GPU 计算一个无需预处理的容易层时,另一组 CUDA 流正在后台解码下一个困难层的权重。等容易层计算完毕、轮到困难层时,它预处理好的数据已经就绪。双缓冲的预处理槽位确保某个困难层的解码输出在仍被消费时不会被覆盖。
down 投影从这种重叠中获益最多:它在 MLP 序列中最后被消费(在 gate、激活和 up 之后),因此它的解码有最长的时间窗口来完成。
自动调优
有四条流水线、多种矩阵乘法内核变体,以及解码与计算之间可调的 SM 划分,配置空间十分庞大。Unweight 没有硬编码单一策略,而是使用自动调优器,在目标硬件上测量实际的端到端推理吞吐量。它先在固定 up 和 down 的情况下扫描 gate 投影的候选配置,再扫描 up,然后是 down,如此反复,直到不再有改进。最终产出一份针对每个模型的配置文件,明确告诉运行时:在每个批大小下,每个投影应使用哪条流水线、哪种矩阵乘法变体以及多少 SM。这一切都由实测性能驱动,而不是启发式规则。
一种压缩格式,多种用途
编码格式、执行流水线和调度是相互独立的选择。同一个经过霍夫曼压缩的模型包既可用于分发,也可用于推理:
- 对于分发,霍夫曼编码可将压缩率做到最大(模型总体积缩减约 22%),从而缩短跨网络传输模型的时间。
- 对于推理,经过霍夫曼编码的投影可在模型加载时转码为调色板中间格式,既能实现最高效的运行时执行,又不会限制分发格式。
单个模型包无需在打包时就锁定某一种策略。运行时会针对每个投影、每个批大小即时选出最佳执行路径。
我们的结果
在 Llama 3.1 8B(我们的主要测试平台)上,Unweight 实现了:
- 推理包的模型占用缩减约 13%(仅压缩 gate/up MLP 投影),分发包则缩减约 22%(压缩包括 down 在内的所有 MLP 投影)。所有压缩均为 100% 逐位精确的无损压缩。推算到 Llama 70B,视配置不同,大约可节省 18–28 GB。
- 在当前优化水平下,吞吐量开销为 30–40%,这是在 H100 SXM5 上端到端测得的结果。开销在批大小为 1 时最大(约 41%),在批大小为 1024 时收窄(约 30%)。三个已知来源,即小批量的固定开销、冗余的权重分块重建,以及被排除在外的 down 投影,正在积极优化中。
这些是基于单一模型的中间结果。压缩率应当可以推广到其他 SwiGLU 架构(指数统计特征在各种模型规模上保持一致),但吞吐量数字取决于当前的内核实现,会随着优化的继续而变化。我们目前还没有压缩注意力权重、嵌入和层归一化,这拉低了整体缩减幅度。
为什么这很重要
GPU 在多个维度上都很昂贵:显卡本身的成本、它们所需的高带宽内存,以及可观的功耗。
为应对这一问题,已有几位研究者展示了在完整模型上压缩率约 30% 的系统,结果令人鼓舞,但它们面向的是消费级 GPU 和研究框架,无法在生产规模下工作。Unweight 研发中的关键洞察在于:多层感知机(MLP)占据了模型权重的大部分,在推理工作负载中也占去相当可观的计算成本。它只压缩 MLP 权重(避免在压缩收益微乎其微的层上引入开销),专为计算与内存高度均衡的数据中心级 H100 GPU 设计,并提供四条随批大小自适应的执行流水线,而不是采用单一方法。
不过,我们要把话说清楚:Unweight 并非免费的午餐。片上重建会增加未压缩权重时本不存在的计算工作。在 Llama 3.1 8B 上,推理配置可节省约 13% 的模型总内存,代价是在典型服务批大小下吞吐量损失约 30%。这一差距在更大的批量下会缩小(预处理的重叠效果更好),随着优化推进预计还会进一步缩小。特别是我们尚未压缩每个 MLP 层中的 down 投影(约占可压缩权重的三分之一),另有若干内核改进正在积极开发中。
对 Cloudflare 的网络而言,Unweight 带来了更好的容量:它让我们能以每个实例更少的 GPU 显存来服务最先进的模型,这意味着成本节省,也意味着能在更多地方部署更多模型。对模型分发来说,节省更大:经过霍夫曼压缩的模型包约小 22%,缩短了向全球边缘节点分发模型的传输时间。
下一步
展望未来,我们有三个具体的研究方向,相信能进一步提升效率收益:
down 投影压缩。Unweight 目前压缩 gate 和 up 两个 MLP 投影,但 down 投影约占可压缩权重的三分之一。由于其维度是转置的,需要另一种内核变体,我们预计这将使模型总体积的缩减超过 22%。
内核优化。目前 30–40% 的吞吐量开销有三个已确认的来源:重建式矩阵乘法在小批量下的固定开销、大批量下冗余的权重重建,以及尚未覆盖的 down 投影。每一项都有已知的缓解路径,我们在技术论文中做了概述。
更多模型。我们的结果来自 Llama 3.1 8B,但底层的指数统计特征在各种规模的 SwiGLU 架构上是一致的。我们正在努力把 Unweight 带到通过 Workers AI 提供服务的更大模型上。
从更长远来看,我们正在研究 Unweight 的架构对混合专家(Mixture-of-Experts)模型意味着什么:在这类模型中,冷专家必须按需获取,存储占用更小将进一步降低成本。
这是一个快速发展的领域,因此我们很高兴能在此开源我们的工作,为压缩和 GPU 效率方面不断增长的研究成果添砖加瓦。Unweight 只是整幅拼图中的一块,但我们希望其他研究者能把它当作有用的范式,在此基础上继续构建!

