DeepSeek总结的OpenZL压缩变换器

来源:https://openzl.org/blog/2026-09-24-compression-transformer/

压缩变换器

Yann Collet

OpenZL 团队

元数据

2026年9月24日

新闻

10 分钟阅读

压缩变换器

让神经网络构建压缩图

OpenZL 通过以任意顺序链接处理层来压缩数据。这很强大,但需要仔细配置:为给定输入选择合适的编解码器组合一直是其最大的挑战。压缩变换器现在可以自动做出这一选择,在压缩过程中逐个决策地动态构建压缩图。它无需针对数据源进行训练,无需手动调优,解压端也无需任何改动。它可从 API 和 CLI 中使用。

图压缩的强大之处------以及复杂性

OpenZL 使用一组可以自由组合成图的编解码器来无损压缩数据。一个图可以将一个输入流推过多个阶段,将其拆分为子流,并为每个子流选择不同的编解码器。这种灵活性很强大:理论上,搜索所有可能的图空间可以为每个输入找到最佳压缩策略。但在实践中,这种搜索在数据压缩过程中执行的成本太高,因此生产系统只能满足于更简单、广泛有效的策略。

可以手动调优图,但这很耗时且难以扩展。这就是 OpenZL 附带训练器 zli train 的原因,它分析数据源的代表性样本,并为该流量生成优化的图。ACE 会生成多个图,涵盖不同的压缩率和速度权衡,让用户选择最符合其约束的那个。

这种方法依赖于两个假设:样本能代表未来的流量,并且流量相当同质。这些假设通常成立。当它们不成立时,训练器不得不折中------一个在样本中不同形态上都能勉强工作的图,但对任何一种形态都不是最优的。

自然的下一步是实时地让图适应每个单独的输入。为每个输入选择图可以处理异构流量、响应异常值,并吸收数据中未宣告的变化,所有这些都无需人工干预或针对数据源的训练。这就是压缩变换器为 OpenZL 带来的能力。

压缩变换器如何工作

压缩变换器从数据流中生成压缩图,一次做一个决策。这里有一个有用的类比:大型语言模型生成文本,因此得名:在每一步,模型根据其当前上下文发出一个标记。在 OpenZL 中,该标记决定一个编解码器及其参数集,即图中的下一个节点。然而,产生的输出并非线性序列。多阶段编解码器会产生子流,模型为每个子流生成决策,递归地构建一个图。

对于每个新流,一个专门评分器------一个小型多层感知机(MLP),每个上下文一个(目前,每个数值元素宽度一个)------评估每个候选编解码器。选择器选出得分最高的有效编解码器并应用它。如果该编解码器产生子流,它们会被反馈给选择器。这样,压缩图就一个节点一个节点地自我组装。

决策循环

一些设计选择使其切实可行且稳健:

  • 跳过阶段:平凡输入,例如空流或常量流,直接处理,不调用神经网络。
  • 评分守卫:确定性规则在评分器对候选排序后拒绝不可能或无意义的操作。它们还会丢弃请求的格式版本中不可用的编解码器,因此生成的图对目标解压器有效。
  • 深度守卫与静态回退:递归有界,低置信度的决策回退到确定性决策树。
  • 标准集成:变换器作为常规选择器插入 OpenZL。它不需要特殊的执行框架。

推理流水线

模型仅在压缩时运行。产生的结果是普通的 OpenZL 帧,由通常的通用解压器读回。

在其第一个实现中,变换器专注于数值类型,并附带四个评分器,每个数值元素宽度(1、2、4 和 8 字节)一个。

结果概览

我们针对 868 个数值流族(总计 34,737 个文件、17.9 GB,每个族代表不同的数据形态)评估了数值变换器。在下面呈现的结果中,变换器与 OpenZL(未训练和已训练)以及两个广泛使用的通用压缩器的最强设置(zstd -19 和 xz -9)进行比较。这些是压缩率参考,不是速度参考:变换器的压缩速度远快于 zstd -19,速度与 zstd -8 到 -12 相当,具体取决于数据宽度。

数字是压缩率的加权几何平均值。"OpenZL 未训练"是 OpenZL 的默认数值路径在默认压缩级别(6)下的表现,使用 Field LZ 压缩;"OpenZL 已训练"使用由 ACE 为每个族单独训练的图。

数值宽度 zstd -19 xz -9 OpenZL 未训练 OpenZL 已训练 变换器 对比 zstd -19
num8 12.26x 10.19x 9.867x 12.23x 12.42x +1.3%
num16 6.772x 6.467x 6.515x 8.415x 8.429x +24.5%
num32 3.056x 3.483x 3.516x 4.390x 4.255x +39.2%
num64 4.578x 5.586x 6.114x 8.723x 8.477x +85.2%
全部 5.752x 5.920x 6.036x 7.846x 7.760x +34.9%

变换器总体与 OpenZL 已训练版本相差在 1.1% 以内,且无需任何按族训练。

有关每种数据类型的详细信息,请参阅以下表格:

  • num8 --- 151 个族中的最佳、中位数和最差
  • num16 --- 226 个族中的最佳、中位数和最差
  • num32 --- 249 个族中的最佳、中位数和最差
  • num64 --- 242 个族中的最佳、中位数和最差

在撰写本文时,变换器在广泛的数值数据形态上表现良好,但其增益并不均匀,而且仍会犯错:在 868 个族中有 95 个落后于 zstd -19,最差情况下落后达 2 倍。这仍处于早期阶段,我们预计随着模型改进,这些差距会缩小。

试用

变换器随 OpenZL v0.3.0 发布,目前为可选启用。从 CLI 中,你可以通过请求压缩级别 7 或更高来查看变换器的运行情况。它适用于直接数值流,或数值子流,例如从解析操作(如 SDDL)中提取的子流。

bash 复制代码
./zli compress --profile le-i32 --level 7 examples/getting_started/sample_inputs/era5_ints.bin --output era5_ints.zl

在此样本上,压缩率从默认级别的 18.95x 提升到级别 7 的 29.41x。

从 C API 中,选择 ZL_GRAPH_TRANSFORMER_NUMERIC 作为起始图,或使用压缩级别 7 或以上的 ZL_GRAPH_NUMERIC:

c 复制代码
#include "openzl/codecs/zl_transformer.h"

ZL_Report r = ZL_Compressor_selectStartingGraphID(
        compressor, ZL_GRAPH_TRANSFORMER_NUMERIC);

从 C++ 中,同一图可作为 openzl::graphs::TransformerNumeric 使用:

cpp 复制代码
#include "openzl/cpp/codecs/Transformer.hpp"

compressor.selectStartingGraph(openzl::graphs::TransformerNumeric::graph);

它接受一个或多个宽度为 1、2、4 或 8 字节的数值流。

如果你想查看模型决定了什么,请在上面的命令中添加 --trace era5_ints.cbor,并在图可视化器中打开该文件------变换器的选择会显示为普通的图节点,因为它们本来就是。

下一步

两个方向已经明确。

首先,我们希望将变换器扩展到数值流之外。其他流类型,如字符串,将在未来的扩展中涵盖。

其次,我们希望将速度作为明确目标,以便选择器能够在规定的性能预算内找到最佳压缩率,而不仅仅是瞄准最强选项。

这些是未来文章的主题。更大的要点已经在这里:压缩图不再需要提前设计或训练。它可以由模型在读取数据的过程中为每个输入动态构建,因此当数据变化时,图也随之变化。而且由于结果是普通的 OpenZL 帧,该模型可以随时间不断变得更智能,而解压器无需更改或重新部署。

相关推荐
想吃火锅10051 小时前
【leetcode】238.除了自身以外数组的乘积js
javascript·算法·leetcode
郝学胜-神的一滴1 小时前
C++ Templates 01:拨开迷雾,读懂C++模板经典著作
开发语言·c++·程序人生·游戏·游戏引擎·软件构建
坤坤子吖1 小时前
算法学习——高精度加减乘除
c++·笔记·学习·算法
CQU_JIAKE1 小时前
10.1[A]2267,磐久UMX【上下文128K,KVCache部分]
算法
朝朝辞暮i1 小时前
C++ 第 14 课:引用 &
开发语言·c++·算法
白山编程大哥2 小时前
适合初学者练习的 C/C++ 开源项目推荐
c语言·c++·开源
Joe_Wang52 小时前
【从0到1学习JVM · 21】既不浪费空间又没有碎片,标记整理算法到底慢在哪
jvm·学习·算法·垃圾回收·标记整理算法
让学习成为一种生活方式2 小时前
PlantCellChat--单细胞与空间转录组数据预测植物细胞间通讯的R包--The Plant Journal
算法
C++ 老炮儿的技术栈2 小时前
有符号变量与无符号变量的区别
服务器·开发语言·前端·数据结构·c++·算法·c