本文已收录于2022年的S&P,一作为香港科技大学的学生。论文为云端在线学习服务提供了一个较为折中的隐私保护方案。

文章目录


  1. 背景及简介
  2. 威胁模型
  3. Sphinx
    1. 设计概览
    2. 设计细节
      1. 基本背景知识
        1. 同态加密
    3. 方案设计
      1. 训练协议设计
        1. 初始化
        2. 训练过程
      2. 推理协议设计
      3. 其它优化
  4. 部分实验结果
  5. 可能的问题
  6. 引用

背景及简介

现如今,机器学习应用越来越普遍。有许多用户选择把他们的模型部署在云端以及在云端进行模型训练。而使用第三方的服务器意味着数据被泄漏的风险增加了。针对这个问题,目前已经有一些方案被提出,比如应用多方安全计算、给模型添加噪声、同态加密、协作学习等等。这些方案或多或少在模型训练或部署方面存在一些问题。

本文提出的Sphinx希望在无可信第三方的基础上,提供一个在线深度学习服务。Sphinx 试图在模型的训练及推理过程中维持一个模型表现、计算效率以及隐私保护之间的平衡。

本文框架运行的逻辑结构如下图所示:

隐私保护的在线机器学习和推理服务
图 1:隐私保护的在线机器学习和推理服务。在此服务中,数据以及模型的参数都不会泄露给服务提供商。(图片截图自论文)

在上图中,用户拥有数据,服务器拥有计算资源。

Sphinx可以使用云端服务器进行模型的训练、推理服务,并且可以在一定程度上保护模型和数据的隐私。

威胁模型

本文考虑一个半诚实的服务提供者,即:服务提供者会遵守和用户之间的协议为用户提供服务,但是服务者对于与用户交互的所有信息都非常好奇。

Sphinx

Sphinx中混合使用了差分隐私(differential privacy, DP)和同态加密(homomorphic encryption, HE)两种技术,并且设计了一个新的协议来达到隐私保护的要求。文中提到两个设计挑战:

  1. 如何设计一个满足特定要求的、高效的、在训练和推理服务中都适用的协议
  2. 如何充分利用混合(DP与HE)协议的优点来最大程度上保护隐私并且维持模型准确率

设计概览

本文的设计假设我们的模型为神经网络,设神经网络为简单的分层结构。设每一层的计算公式为:

$$ f(x) = \sigma(W^T \mathbf{x} + \mathbf{b}) $$

其中$\sigma$为非线性激活函数(以及池化操作等),$W$为权重向量,$\mathbf{b}$为偏置。

Sphinx使用HE对偏置$\mathbf{b}$进行加密,使用DP对权重$W$的计算进行扰动。协议的设计考虑了性能问题,此处如果完全使用HE,那计算速度会大打折扣。所以对于权重的计算仅使用了DP的方案(明文)。此外,针对HE,文中还另有一些优化细节。

在Sphinx的设计中,非线性部分($f$)是在用户端完成的,显然这在计算过程中引入了用户端与服务器端之间的交互,会在一定程度上影响计算效率。

设计细节

基本背景知识

同态加密

论文中使用的加密方案为CKKS 同态加密方案,感兴趣的可以去研究相关论文。这里给出此方案的几个特性。CKKS 支持在密文上的加法和乘法操作,即给定两个明文$m_1, m_2$,以及其对应的密文$ct_1=Enc(m_1), ct_2=Enc(m_2)$,那么对于CKKS我们有:

$$ \begin{align} Dec(ct_1 + ct_2) \approx Dec(ct_1) + Dec(ct_2) = m_1 + m_2\ \text{ ; 加法同态} \\ Dec(ct_1 \times ct_2) \approx Dec(ct_1) \times Dec(ct_2) = m_1 \times m_2\ \text{ ; 乘法同态} \end{align} $$

其中$Enc$为加密操作,$Dec$为解密操作,上面的等式中我们使用了约等于号$\approx$是因为,此方案解密出的明文为一个近似值(可调节精度),实际上,这点误差在一般神经网络的训练中影响不大。

同时,CKKS 还支持明文与密文之间的混合操作,并且明文与密文之间的计算相对于密文与密文之间的操作,计算量要小很多。这一点在Sphinx协议的设计中被很好地利用以提升性能。

方案设计

给定一个样本输入$\mathbf{a}$,那么神经网络的计算可以公式化为:

$$ \mathbf{a}_{i+1} = f(W_i^T \mathbf{a}_i + \mathbf{b}_i) $$

其中$\mathbf{x}_i$为第$i$层的输入,其中$\mathbf{a}_1 = \mathbf{a}$,也就是输入数据;$f$为一个组合函数,其中包含了激活函数、池化等操作。我们将神经网络的参数分为两部分:

  1. 线性部分$W_1, W_2, \ldots, W_K$,我们称这部分为线性单元
  2. 平移部分$\mathbf{b}_1, \mathbf{b}_2, \ldots, \mathbf{b}_K$,我们称这部分为偏置单元

训练协议设计

我们回顾一下我们逻辑结构:用户拥有数据,但是没有计算资源;而云端服务器拥有计算资源。那么训练协议工作流程如下。

初始化

首先用户生成一对公私钥对$PK, SK$,并且将公钥$PK$以及初始模型结构发送给服务器。服务器初始化模型参数,其中线性单元为$W^0$,偏置单元为使用公钥$PK$加密后的$[b^0]$(下文中所有$[x]$表示对$x$加密后的结果)。

训练过程

首先,用户采样一批样本$\mathbf{a}_1 = \{ \mathbf{x}_1, \mathbf{x}_2, \ldots, \mathbf{x}_B \}$,然后将样本$\mathbf{a}_1$加密得到$[\mathbf{a}_1]$,然后将加密后的数据$[\mathbf{a}_1]$发送给服务器。那么对于每一层的神经网络,它的计算过程应为:

$$ [\mathbf{a}_{i+1}] = f(W_i^T [\mathbf{a}_i] + [\mathbf{b}_i]) $$

对于服务器而言,它进行$W_i^T[\mathbf{a}_i] + [\mathbf{b}_i]$的计算得到一个中间的密文,记为$[\mathbf{c}_i]$。而后,服务器将$[\mathbf{c}_i]$发送给用户端进行解密。用户端收到$[\mathbf{c}_i]$后,进行如下运算:

$$ [\mathbf{a}_{i+1}] = Enc(f(Dec([\mathbf{c}_i]))) $$

即用户端进行三步运算:(1) 解密;(2) 池化及非线形激活函数$f$的计算;(3) 对激活的结果进行加密得到$[\mathbf{a}_{i+1}]$。而后,用户将第$i+1$层的输入$[\mathbf{a}_{i+1}]$发送给服务器进行下一层的运算。

为了反向传播时,减少通信量,此时用户端可以将$f$的一阶导数$Enc(f^\prime(Dec([\mathbf{c}_i])))$一起运算出来,并发送给服务器缓存起来。

那么按照这样的方式计算直到所有层都计算完毕。此过程完成了神经网络的前向计算。对于反向传播,首先我们有损失函数公式:

$$ \mathcal{L} = \mathcal{L} (\mathbf{a}_K, y) $$

那么我们有:

$$ \begin{align} \cfrac{\partial \mathcal{L}}{\partial b_i} &= \cfrac{\partial \mathcal{L}}{\partial a_{i+1}} \odot \cfrac{\partial \mathbf{a}_{i+1}}{\partial \mathbf{b}_{i}} \\ &= \cfrac{\partial \mathcal{L}}{\partial \mathbf{a}_{i+1}} \odot \cfrac{\partial f(W_i^T \mathbf{a}_i + \mathbf{b}_i)}{\partial \mathbf{b}_i}\\ &= \cfrac{\partial \mathcal{L}}{\partial \mathbf{a}_{i+1}} \odot f^\prime(W_i^T \mathbf{a}_i + \mathbf{b}_i) \end{align} $$
$$ \begin{align} \cfrac{\partial \mathcal{L}}{\partial W_i} &= \cfrac{\partial \mathcal{L}}{\partial a_{i+1}} \odot \cfrac{\partial \mathbf{a}_{i+1}}{\partial \mathbf{W}_{i}} \\ &= \cfrac{\partial \mathcal{L}}{\partial \mathbf{a}_{i+1}} \odot \cfrac{\partial f(W_i^T \mathbf{a}_i + \mathbf{b}_i)}{\partial \mathbf{W}_i}\\ &= \mathbf{a}_i (\cfrac{\partial \mathcal{L}}{\partial \mathbf{a}_{i+1}} \odot f^\prime(W_i^T \mathbf{a}_i + \mathbf{b}_i))^T \end{align} $$
$$ \begin{align} \cfrac{\partial \mathcal{L}}{\partial a_i} &= \cfrac{\partial \mathcal{L}}{\partial a_{i+1}} \odot \cfrac{\partial \mathbf{a}_{i+1}}{\partial \mathbf{a}_{i}} \\ &= \cfrac{\partial \mathcal{L}}{\partial \mathbf{a}_{i+1}} \odot \cfrac{\partial f(W_i^T \mathbf{a}_i + \mathbf{b}_i)}{\partial \mathbf{a}_i}\\ &= \mathbf{W}_i \cfrac{\partial \mathcal{L}}{\partial \mathbf{a}_{i+1}} \odot f^\prime(W_i^T \mathbf{a}_i + \mathbf{b}_i) \end{align} $$

其对应的加密版本为:

$$ \begin{align} \left[\cfrac{\partial \mathcal{L}}{\partial b_i}\right] & = \left[\cfrac{\partial \mathcal{L}}{\partial \mathbf{a}_{i+1}}\right] \odot f^\prime(W_i^T [\mathbf{a}_i] + [\mathbf{b}_i])\\ \left[\cfrac{\partial \mathcal{L}}{\partial W_i}\right] & = [\mathbf{a}_i] \left(\left[\cfrac{\partial \mathcal{L}}{\partial \mathbf{a}_{i+1}}\right] \odot f^\prime(W_i^T [\mathbf{a}_i] + [\mathbf{b}_i])\right)^T\\ \left[\cfrac{\partial \mathcal{L}}{\partial a_i}\right] & = \mathbf{W}_i \left(\left[\cfrac{\partial \mathcal{L}}{\partial \mathbf{a}_{i+1}}\right] \odot f^\prime(W_i^T [\mathbf{a}_i] + [\mathbf{b}_i])\right) \end{align} $$

计算出这些加密的梯度之后:

  • 对于偏置单元,服务器本身拥有的就是加密版本。因此,直接将偏置单元的梯度更新到模型中即可
  • 对于线形单元,服务器中存储的为明文版本。此时,服务器需要将梯度发送给用户端解密,而后将解密后的线形单元的梯度更新到模型中去。这里需要注意的是:文中对梯度进行了截断,以保证梯度的二范数小于一个常数$C$,这样可以保证后续添加的噪声足够强以满足隐私要求;客户端在对解密后的线形单元的梯度发送给服务端之前,会使用**差分隐私 (DP)**在梯度之中加入噪声,以增强数据隐私

笔记:文中算法一中客户端的阶段操作max是不是应该是min???

推理协议设计

在训练过程中,我们使用的前向推理中,包含了(同态)加密操作:

  1. 用户需要使用私钥对样本进行加密
  2. 服务器需要进行同态乘法(明文$\times$密文)和同态加法(密文$+$密文)操作

鉴于部署推理服务后,用户的数据可能是一个流的形式不停地向服务器发送请求,那么为了保证推理服务的性能,论文设计了一个优化方案。此方案可以通过预处理阶段,率先计算出很多共享密钥(每次推理使用一个不同的共享密钥),来避免推理时耗时的同态加密操作。

单个共享密钥生成方式:

  1. 用户对每一层神经网络的输入生成一个mask向量$r_i$,服务器为每一层神经网络的输出生成一个mask向量$s_i$
  2. 用户将每一层的$r_i$加密后得到$[r_i]$,并将加密后的$[r_i]$发送给服务器
  3. 服务器计算出各层的$\mathbf{W}_i^T \cdot [\mathbf{r}_i] + [\mathbf{b}_i] - \mathbf{s}_i \to [\mathbf{W}_i^T\cdot \mathbf{r}_i + \mathbf{b}_i - \mathbf{s}_i]$,并将结果发送给客户端
  4. 客户端解密得到:$\mathcal{P}_i = \mathbf{W}_i \cdot \mathbf{r}_i + \mathbf{b}_i - \mathbf{s}_i$

样本$\mathbf{x}$推理过程 :

  1. 客户端挑选某个mask$\mathbf{r}_i$,计算$\mathbf{x} - \mathbf{r}_i$,并将$\mathbf{x} - \mathbf{r}_i$发送给服务器
  2. 服务器计算$W_i^T \cdot (\mathbf{x} - \mathbf{r}_i) + s_i$,并将其发送给用户
  3. 用户计算$\mathcal{P}_i + W_i^T \cdot(\mathbf{x} - \mathbf{r}_i) + s_i \to W_i^T \cdot \mathbf{x} + \mathbf{b}_i$

这里所有的操作都是在素数域进行的。

其它优化

文中提到了其它一些优化点,感兴趣可自行查看。

部分实验结果

这里我们看下Sphinx与纯同态加密方案在训练过程中,执行时间与通信量上的对比结果。实验中使用了MNIST和CIFAR10数据集,神经网络结构不重要,感兴趣可查看论文。

单个批次数据(batch)的训练时间
图 2:单个批次(batch)的训练时间。(图片截图于论文)
单个批次数据(batch)的每张图片通信量
图 3:单个批次数据(batch)每张图片的通信量。(图片截图于论文)

可以看到Sphinx 在训练执行时间与通信量上相比纯HE方法有很大改进。

在推理速度上,Sphinx相比于先前的方法也有不错的改进,感兴趣可查看论文。

可能的问题

  1. 每轮训练都要发送全部的线形单元的梯度(而且每个样本都要分别发送各自的梯度),很难实际应用(特别是在网络不好/模型太大时)
  2. 由于线形单元是明文,即使偏执单元不知道,服务器若有点数据,那么可以复制一个模型,将线形单元固定,只训练bias,经过二次训练应该比较容易恢复出原有模型
  3. 模型结构暴露了

引用

[1] H. Tian, et al., "Sphinx: Enabling Privacy-Preserving Online Learning over the Cloud," in 2022 2022 IEEE Symposium on Security and Privacy (SP) (SP), San Francisco, CA, US, 2022 pp. 1135-1149.


[本]通信工程@河海大学 & [硕]CS@清华大学
这个人很懒,他什么也没有写!

1
8492
1

More Recommendations