
【新智元导读】LLM 的规模爆炸式增长,传统量化技术虽能压缩模型,却以牺牲精度为代价。莱斯大学团队的最新研究 DFloat11 打破这一僵局:它将模型压缩 30% 且输出与原始模型逐位一致!更惊艳的是,通过针对 GPU 的定制化解压缩内核,DFloat11 使推理吞吐量提升最高 38.8 倍。
人人都想有一个自己的 DeepSeek,但并不是人人都有「一打」96GB 显存的 H20。
虽然量化可以极大地降低模型对于显存的需求,但它本质上是一种有损压缩技术。
换句话说就是,量化模型的输出分布不可避免地会受到影响,进而降低 LLM 的准确性和可靠性。

为此,来自莱斯大学等机构的研究人员提出了一种全新的无损压缩框架------动态长度浮点数(DFloat11),它能够将 LLM 的大小减少 30%,同时确保输出结果与原始模型逐位相同。

为了支持使用动态长度编码进行高效推理,团队专门开发了一个定制的 GPU 内核,用于实现快速的在线解压缩:
-
将内存密集型的查找表 (LUT) 分解为更紧凑的 LUT,使其能够完全放入 GPU 的 SRAM 中;
-
一个双阶段内核,利用轻量级的辅助变量来协调线程的读写位置;
-
Transformer Block 级的解压缩,从而最大限度地降低延迟。
在 Llama-3.1、Qwen-2.5、Gemma-3 等 SOTA 模型上的实验表明, DFloat11 除了能有效压缩模型的大小之外,同时还能保持完全一致的输出结果。
与将模型的部分数据卸载到 CPU 的方案相比,DFloat11 在 Token 生成任务中实现了 1.9 到 38.8 倍的吞吐量提升。
在 GPU 显存固定的情况下,DFloat11 能够支持比未压缩模型长 5.3 到 13.17 倍的上下文长度。
特别值得一提的是,DFloat11 成功地实现了 Llama-3.1-405B(810GB)在单节点上(8 块 80GB GPU)的无损推理。
Llama-3.1-405B 拥有 4050 亿参数,采用 16 位 Brain Float(BFloat16)格式,需要约 810GB 内存才能实现完整推理,超过了典型 GPU 服务器的容量(如配备 8×80GB GPU 的 DGX A100/H100)。

本文一作 Tianyi Zhang,是莱斯大学计算机科学专业的博士生,之前在滑铁卢大学获得计算机科学学士学位。


为什么要对 LLM 进行无损压缩?
在目前的有损量化技术中,模型通常被压缩到更低的位宽度(如 8 位或 4 位)。
虽然部分基准测试表明,8 位量化是一种相对「安全」的压缩方案,但在实际体验时终究不如无损的模型。
例如,LLM Arena 上的人工评估显示,Llama-3.1-405B-Instruct 及其 8 位版本(Llama-3.1-405B-Instruct-FP8)之间的性能存在显著下降,尤其是在编码和长查询任务中。
类似的,将 DeepSeek-R1-Distill-Llama-70B 从 16 位量化到 8 位会导致 GPQA 上的性能下降 23.7%(从 9.51% 降至 7.25%)。
此外,推理作为现代 LLM 的核心能力,似乎对压缩损失特别敏感。
一些基准测试表明,使用 8 位 SmoothQuant(用于权重、注意力和 KV 缓存)量化的 DeepSeek-R1-Distill-Qwen-1.5B,会在 AIME、MATH-500、GPQA-Diamond 和 LiveCodeBench 等数据集上的推理性能,平均下降 9.09%(从 48.82% 降至 44.29%)。
有损压缩降低质量,无损压缩缺乏效率
相比之下,无损压缩技术在有效减小大规模 LLM 大小的同时,能够保留其精确的原始权重,确保模型的输出分布与未压缩表示(例如 BFloat16)的输出分布完全一致。
然而,现有的无损压缩方法主要侧重于提高 LLM 的存储效率,例如缩小模型检查点,或者优化诸如 FPGA 等专用硬件的性能。
这些方法虽然有利于训练过程中的高效检查点回滚,或者从 Hugging Face 等模型仓库加速下载,但其优势通常难以有效地扩展到基于 GPU 的 LLM 推理。

实验方法
为了推动 LLM 权重的无损压缩,团队分析了最新 LLM 权重中 BFloat16 各个组成部分(符号、指数和尾数)的可压缩性。
具体来说,团队使用香农熵来量化 LLM 线性投影矩阵中参数的信息量。香农熵 H(·) 定义如下:

其中 X 是一个离散随机变量,其所有可能取值的集合为χ,p:χ→[0,1] 表示其概率质量函数。
如图 1 所示,符号和尾数部分的熵值与其对应的位宽接近,说明它们的可压缩空间不大。相比之下,指数部分的熵值明显较低,只有约 2.6 位,但其分配的位数为 8 位,这意味着无损压缩存在很大的机会。

无损 LLM 压缩框架,实现高效 GPU 推理
为了解决 LLM 权重在 BFloat16 表示中存在的巨大信息冗余问题,团队提出了一种利用熵编码来对浮点参数进行编码的无损压缩框架------DFloat。
首先,基于 LLM 线性投影矩阵中所有 BFloat16 权重的指数分布构建一个 Huffman 树。
然后,使 Huffman 编码压缩指数部分,同时保留原始的符号位和尾数。
指数被编码后,紧密地打包到 EncodedExponent 字节数组中,而符号位和尾数则保持未压缩状态,存储在另一个 PackedSignMantissa 字节数组中。

动态长度浮点数格式可以紧凑地表示浮点模型参数
使用紧凑 LUT 实现高效解码
由于 Huffman 编码可以通过机遇查找表(Lookup Table,LUT)的方法有效地解码,于是团队构建了一个大小为 2^L 的 LUT,其中 L 是码本中任何 Huffman 编码的最大位长度。
为了进行解码,团队从编码的位流中读取接下来的 L 位,并将它们作为 LUT 的索引来获取下一个解码后的符号。
为了解码 DFloat11 格式的指数,限制每个模型的最大代码长度 L 为 32 位。
对于那些 L 大于 32 的模型,团队通过将最不常见的指数的频率降低到 1 并重新构建 Huffman 树来强制满足长度约束。
如此,便会在 Huffman 树的尾部产生一个更加平衡的结构,为最稀有的指数分配相同长度的代码,并将最大代码长度缩减到 3 位。
然而,当 L=32 时,直接使用查找表将需要 232≈42.9 亿个条目,这将消耗巨大的内存。
为了解决这个问题,团队提出将这个庞大的 LUT 分割成四个互不相交且节省内存的查找表------LUT1、LUT2、LUT3 和 LUT4。
这样一来,内存占用就可以完全放在 GPU SRAM 中,从而实现快速访问。
两阶段 Kernel 和轻量级辅助变量
为了能够对 DFloat11 格式中经过熵编码的指数进行大规模并行解码,团队为每个线程分配一段固定长度的、来自编码序列的字节来进行处理。
然而,这种方法会带来两个主要的挑战:
-
由于 Huffman 编码的位宽是可变的,并且编码后的数据是被紧密地打包在一起的,因此每个线程开始解码的起始位位置并不明确。
-
除了第一个线程之外,其他线程所要解码的元素的索引是未知的,这导致难以确定用于存储解码结果的正确输出位置。
为了解决第一个问题,团队使用一个间隙数组来确定每个线程的起始位位置。
这个间隙数组 Gaps 为每个线程包含一个条目,每个条目都指定了相对于该线程所分配的起始字节,第一个有效 Huffman 编码的位偏移量。由于最大代码长度为 32 位,因此每个偏移量的值都在 [0,31] 范围内。为了保证内存效率,团队使用 5 个位来编码每个条目。
为了解决第二个问题,最直接的方法是维护一个数组,用于存储每个线程所解码的第一个元素的输出位置。然而,这种方法会带来巨大的存储开销。
为了减少存储开销,团队只存储每个线程块中第一个元素的输出位置,而不是存储每个线程的输出位置。
为了能够使用块级的输出位置信息进行解码,团队采用了一种两阶段的 Kernel 设计。
在第一阶段,一个线程块内的所有线程并行地解码分配给它们的那部分编码序列,但是并不将任何输出结果写入到全局内存中。取而代之的是,每个线程会计算它将要解码的元素的数量。
完成这一步之后,团队同步同一个线程块内的所有线程,并通过计算前缀和来确定每个线程的输出位置,计算前缀和的起始位置是该线程块的已知输出位置。
在第二阶段,每个线程会重新解码相同的那部分编码序列,这一次会将解码后的结果写入到 HBM 中正确的输出位置。
为了避免在这两个阶段中重复访问 HBM,团队将编码后的指数数据加载到 SRAM 中。

两阶段 Kernel 的伪代码
Transformer Block 级解压缩
至此,就有了一套完整的方法,可以对经过熵编码的指数进行大规模并行解压缩。
LLM 的权重以 DFloat11 格式存储,同时还包含轻量级的辅助数据:线程级的间隙偏移量以及块级的输出位置,这些数据用于确定每个线程的读取和写入位置。
在推理过程中,压缩后的权重数据和这些辅助变量都完全驻留在 GPU 上。
当需要使用某个权重矩阵进行矩阵乘法运算时,该矩阵会被动态地解压缩为原始的 BFloat16 格式。一旦矩阵乘法运算完成,这个 BFloat16 格式的矩阵会立即被丢弃,以节省 GPU 显存。
在实际应用中,由于单个权重矩阵的尺寸通常相对较小,因此单独解压缩一个权重矩阵往往无法充分利用 GPU 资源。
在 DFloat11 解压缩 Kernel 中,将每个线程处理的字节数设置为 n=8,每个线程块中的线程数设置为 T=256,线程块的数量设置为 B=⌈|EncodedExponent|/(nT)⌉,其中 | EncodedExponent | 表示编码后的指数数据所占的总字节数。
随着 DFloat11 格式的权重数据尺寸的增加,会有更多的线程块被利用起来,从而可以提高整体的解压缩吞吐量。
图 6 展示了这种现象,它表明解压缩的吞吐量会随着矩阵尺寸的增加而显著提升。为了充分利用这一特性,研究团队建议将多个矩阵的解压缩操作进行批处理,以此来提高吞吐量并隐藏延迟。

更具体地说,可以将单个 Transformer Block 内的所有 DFloat11 格式的权重矩阵的解压缩操作进行批处理。
在 Transformer Block 中执行任何计算操作之前,团队首先解压缩与其相关联的所有权重数据。这种方法能够显著降低解压缩的延迟,并提高整体的推理效率。
图 5 展示了在不同的批处理大小下,使用 DFloat11 压缩的 Llama-3.1-8B-Instruct 模型的延迟细分情况。


实验结果
DF11 将 LLM 压缩至 70% 大小
表 2 展示了 DF11 对多种最新 LLM 的压缩比率。
压缩的模型包括 LLaMA3/3.1/3.3、Qwen2.5、QwQ、Mistral Nemo/Small/Codestral、Gemma2/3 以及 DeepSeek-R1-Distilled。
实验结果显示,DF11 对所有模型的压缩比约为 70%,相当于大约 11 位的有效位宽。

DF11 压缩完全无损
研究团队通过一系列标准基准测试验证了 DF11 压缩的无损特性。
评估使用 lm_evaluation_harness 工具进行,报告了 MMLU 和 TruthfulQA 的准确率,以及 WikiText 和 C4 的词级困惑度。
如表 3 所示,压缩模型的准确率和困惑度与原始 BF16 模型完全一致。
为了进一步验证无损特性,他们将 DF11 解压后的 BF16 权重矩阵与表 2 中各模型的原始权重矩阵进行比较,确认两者在比特级上完全相同。

DF11 在推理效率上超越 CPU 卸载
研究团队比较了 DF11 和 BF16 模型在不同硬件平台上的推理效率。
未压缩的 BF16 模型通常会超出单个 GPU 的显存限制,而无损压缩的 DF11 模型则不会超出。
对于 BF16 模型,团队将模型的大部分内容和计算保留在 GPU 上,同时将部分组件及其相关计算卸载到 CPU 上。
如图 3 所示,DF11 模型始终优于采用 CPU 卸载的 BF16 模型,延迟降低了 1.85 至 38.83 倍或吞吐量更高。

DF11 支持更长的生成长度
DF11 压缩带来的显存节省不仅减少了推理所需的 GPU 数量,还支持更长的生成长度。
在推理过程中,KV 缓存会随着解码 token 数量的增加而线性增长,很快成为 GPU 显存的瓶颈。
图 4 展示了在批大小为 1 时,DF11 和 BF16 模型在推理过程中随着解码 token 数量增加的 GPU 显存消耗情况。
如图所示,DF11 压缩显著延长了 token 生成长度,与 BF16 模型相比,在达到 GPU 显存限制前能解码 5.33 至 13.17 倍的 token 数量。


结论
在这项工作中,研究人员提出了动态长度浮点(DFloat)作为一种针对 LLM 权重的无损压缩数据格式。DFloat 是目前唯一一种既能减少显存占用又兼容高效 GPU 推理的数据格式。
具体来说,他们使用 11 位的 DFloat 格式(DF11)评估了多个热门 LLM,并为此格式开发了定制的 GPU 内核。
实验结果表明,基于 DF11 的压缩显著降低了服务 LLM 的硬件需求,而且在大多数实际应用场景下,它所增加的额外计算负担也是可以接受的。
参考资料: