0%

SketchML

框架总览

三个组件,前两个组件压缩梯度值,第三个组件压缩梯度键

  • Quantile-Bucket Quantification
  • MinMaxSketch
  • delta encoding

image-20220117163006463

编码阶段

  • Quantile Sketch用于生成候选分割,我们使用桶排序来总结梯度值。
  • 梯度值由桶的索引表示。
  • 通过对键应用哈希函数,将桶索引插入MinMaxSketch。
  • 将梯度键转换为增量,本文用增量键表示。
  • 我们使用二进制编码用更少的字节来编码delta键,而不是使用四字节整数。

解码阶段

  • 增量键恢复到原始键。
  • 使用恢复的密钥查询MinMaxSketch。
  • 每个值的桶指数由示意图得到。
  • 通过使用bucket索引查询bucket值来恢复该值。

Quantile-Bucket Quantification

image-20220117163024927

步骤1:分位数分裂

  • 我们扫描所有的梯度值并将它们插入分位数草图。
  • q分位数用于从分位数草图中提取候选分位数。具体来说,我们生成了q的平均分位数{0,1/q,2/q,…,q-1/q}。
  • 我们使用分位数和最大值作为分割值,用{rank(0),rank(1/q), rank(2/q),…,rank(1)}。注意,值位于两个连续分割之间的项的数量是N/q,这意味着我们用项的数量而不是值除以项的数量。两个分割之间的每个区间都有相同数量的梯度值。

步骤2:桶排序

  • 我们称两次分割之间的每个间隔为一个桶。
  • 较小的分割是桶的较低阈值,较大的分割是较高的阈值。
  • 根据桶的阈值,每个梯度值属于一个特定的桶。例如,图3中0.21的值被分类到第四个桶中。
  • 每个桶用均值表示,即平均值。
  • 将每个梯度值转换为对应的桶均值。

步骤3:索引编码

虽然我们用桶的平均值来量化梯度值,但是所消耗的空间是相同的。为了降低空间成本,我们选择了存储bucket索引的替代方法。我们将桶的平均值编码为桶索引。例如,将0.21量化为用均值表示的第四个桶之后,我们通过桶索引从零开始对其进行编码,即0.21对应的是数字3。

步骤4:二进制编码

通常,桶的数量是一个小整数。我们通过将bucket索引编码为二进制数来压缩它们。如果q=256,一个字节就足够对bucket索引进行编码。通过这种方式,我们将占用的空间减少,我们可以在很大程度上减少传输的数据。

MinMaxSketch

image-20220117163034204

插入的阶段

  • 每个输入项由原始密钥已编码的桶索引(kj,b(vj))组成。

  • 使用s哈希函数计算哈希码。在图5中,有三个哈希函数,h1(-)、h2(-)和h3(-)。

  • 在第i个哈希表中选择一个哈希bin后,比较当前值H(i,hi(kj))和b(vj)。如果H(i,hi (kj)) > b(vj),我们用b(vj)替换当前值。否则,我们不更改当前值。

查询阶段

  • 输入为梯度键,用kj表示。s哈希函数应用于kj,每个哈希函数从哈希表中选择一个哈希bin。

  • 给定不同行的s个候选项,选择最大的作为最终结果。在图5中,三个候选项是{0,2,2},我们选择2作为结果。

Delta-Binary Encoding

image-20220117163041742

通过对梯度键数据分布的分析,发现梯度键具有三个特征。

  • 首先,键是非重复的。

  • 其次,键按升序排列。

  • 第三,尽管在许多高维应用中键可以非常大,但是相邻键之间的差别要小得多。

基于以上三点,我们建议只存储键的增量。

步骤1:增量编码

梯度键存储在数组中。我们从头到尾扫描数组,并计算两个相邻键之间的差值。然后,我们得到键的增量,我们称之为键。

步骤2:二进制编码

  • 通过增量编码,很明显增量键要比原始键小得多。

  • 如果我们以整数或长整数的格式存储delta键,那么压缩是没有意义的,因为所消耗的内存空间和通信成本保持不变。

  • 为了解决这个问题,我们将不同的空间分配给不同的delta键,并将它们编码为二进制格式。