ai算子是什么_隐私AI框架中的数据流动与工程实现
在上一篇文章中,我們介紹了,對于安全技術開發者,如何快速的基于 Rosetta 等隱私 AI 框架所提供的一系列接口,將自己的安全協議集成落地到上層的 AI 應用中來。在這一篇文章中,我們將介紹為了保護用戶的隱私數據,在隱私 AI 框架的計算任務全流程中,數據是如何以密文形式流動,同時仍正確完成加法、乘法等計算步驟的。
隱私 AI 系統存在的目的就是賦能 AI,使得各種 AI 場景下對用戶隱私數據的使用都是安全的。那么,這樣的系統就需要提供充分的保障,從理論到工程實現的每一個階段都應該是經得起推敲、抵抗得住各種攻擊的。不能簡單的認為只需要各方先在本地自己的數據上計算出一個模型,然后將模型結果交換一下計算下其模型參數的平均值,就不會泄露各方的隱私數據了。現代密碼學(Cryptography)是建立在嚴格的數學定義、計算復雜度假設和證明基礎之上的,其中 MPC (Multi-Party Computation)方向是專門研究多個參與方如何正確、安全的進行聯合計算的子領域, Rosetta 、 TF Encrypted 等隱私 AI 框架都采用了 MPC 技術以提供可靠的安全性。下面我們就結合具體案例看的看下在 Rosetta 中隱私數據是如何得到安全保護的。
案例
Alice, Bob 和 Charley 三人最近需要在他們的 AI 系統中引入對數據的隱私保護能力。他們很重視安全性,所以他們想通過一個簡單的例子 —— 乘法(multiply),來驗證下隱私 AI 框架是否真正做到了隱私安全。
他們約定:Alice 的輸入為 1.2345;Bob 的輸入為 5.4321;而 Charley 拿到相乘的結果。
他們按照 Rosetta 提供的教程,快速編寫了如下代碼(腳本名為 rosetta-mul.py):
#!/usr/bin/env python3import latticex.rosetta as rttimport tensorflow as tf rtt.activate("SecureNN")x = tf.Variable(rtt.private_console_input(0, shape=(1,))) # Alice's inputy = tf.Variable(rtt.private_console_input(1, shape=(1,))) # Bob's inputz = tf.multiply(x, y) # z = x * ywith tf.Session() as sess: sess.run(tf.global_variables_initializer()) res = sess.run(rtt.SecureReveal(z, receive_party=4)) # 'b0100' means Charley print('z:', res)rtt.deactivate()接著,他們各自打開一個終端,分別進行如下操作:
Alice (P0) 在終端敲下如下命令行,并根據提示輸入自己的私有數據:
$ python ./rosetta-mul.py --party_id=0please input the private data (float or integer): 1.2345Bob (P1) 執行同樣的操作,輸入的也是只有自己才知曉的私有數據:
$ python ./rosetta-mul.py --party_id=1please input the private data (float or integer): 5.4321Charley (P2) 在終端敲下如下命令行,等一會兒就可以得到所期望的計算結果:
$ python ./rosetta-mul.py --party_id=2z: [b'6.705910']注:
對于 Charley 來說,由于沒有數據,故不會提示輸入。Alice 和 Bob 的本地輸出都會是 z: [b'0.000000'], 而不會拿到正確的結果。
可以看出,Charley 拿到的最終結果與邏輯上明文結果(6.70592745)相比,誤差(0.00001745)可以忽略不計。系統的正確性得到了驗證。
如果想讓誤差更小,可以通過配置提升精度,或使用 128-bit 的數據類型。具體操作可以參考文檔。
上面短短的幾行代碼,雖然結果是正確的,但是他們三人對于系統安全性方面仍有一些困惑:
- Alice、Bob 的私有輸入會不會被另外兩方知道?
- Charley 拿到的結果會不會被 Alice 、 Bob 知道?
- 整個程序運行過程中,有沒有其他數據的泄漏?
- 如果前幾問的回答都是否定的,那 Charley 又是如何得到明文?
在回答這些問題之前,為簡化描述、突出本質,我們需要簡單介紹一下 MPC 實際落地中常用的安全假設。
假定系統中有 3 個節點,P0/P1/P2,其中 P0/P1 為數據參與方,而P2 是輔助節點,用于隨機數生成。
- 只考慮半誠實(Semi-Honest)安全模型,即三方都會遵守協議執行的流程,并且其中誠實者占多數(Honest-Majority),也就是說三個節點中只會有一個“壞人”。更為復雜的惡意(Malicious)模型等安全場景可參考其他相關論文。
- 內部數據類型為 64 位無符號整型,即 uint64_t (這在理論上對應著在環 Z264Z264 )。
下面我們就按照 輸入–計算–輸出 的順序,詳細介紹 Rosetta 中數據的表示與流動,以及所用到相關技術與算法在工程上的優化實現。
隱私數據的輸入
隱私計算問題,首先要解決的是隱私數據的輸入。
在上述案例中,是通過如下兩行代碼來完成私有數據的安全輸入的:
x = tf.Variable(rtt.private_console_input(0, shape=(1,))) # Alice's inputy = tf.Variable(rtt.private_console_input(1, shape=(1,))) # Bob's input如代碼所示,rtt.private_console_input 是 Rosetta 眾多 API 之一,Rosetta 還提供了 rtt.private_input、rtt.PrivateDataset 等 API,用來處理隱私數據的輸入。
這里發生了什么?x,y 的值會是什么?
在進入剖析之前,先來了解一個重要的概念 —— 秘密分享。
秘密分享
什么是 秘密分享(Secret Sharing)[1]?先來看一種簡單的兩方 additive 的構造:
給定一個數 x,定義 share(x) = (x0, x1) = (x ? r, r),其中 r 是隨機數,并且與 x 獨立。可以看到,x = x0 + x1 = x -r + r。原始數據 x 的秘密分享值 (x0, x1) 將會由兩個數據參與方 (P0, P1) 各自保存。
在秘密分享的方案中,所有的數據,包括中間數值都會分享在兩個參與方之間。直觀的看,參與的兩方不會得到任何的明文信息。理論上,只需要在環 Z264Z264 上支持加法和乘法,就可以進一步通過組合來支持上層各種更復雜的函數。下文我們會看到關于乘法的詳細解析,讀者可以回過頭來再看這段話。
那工程上是如何處理的呢?假設 P0 有一個私有數據 x,三方之間可以簡單交互一下實現:
方案 1: P2 生成一個隨機數 r,發送給 P0/P1。然后 P0 本地設置 x0 = x - r,P1 本地設置 x1 = r。此時 share(x) = (x0, x1) = (x - r, r),與上面的定義一致。
這是方案之一,后文基于這個方案進行講解。在本文最后,我們會提一下實際落地時的進一步優化方案。
回到主線,結合 方案 1,我們以 Alice 的輸入值 x = 1.2345 為例看下具體過程。
第一步,浮點數轉定點數。
對于有數據輸入的一方,需要先將真實的浮點數轉成定點數。
浮點數轉定點數:即浮點數乘以一個固定的縮放因子(scale,一般為 2k2k )使其變成定點數(取其整數部分,舍棄小數部分)。當最后需要還原真實的原始浮點數時,用定點數除以縮放因子即可。
我們先選定一個縮放因子,這里取 scale = 218218 。
經過縮放后,得到 x = 1.2345 * (1<<18) = 323616.768,取整數部分即 323616,用于后續計算。
這里是有精度損失的,但在精度允許的范圍內,不會影響后面的計算。
第二步,生成隨機數 r。 也叫掩碼(Masking value),用來隱藏真實值。
P2 生成一個隨機數 r,是一個 64-bit 空間的無符號整數。(如,r = fdad72ecbfbefeb9。這里用十六進制表示,下同)
P2 將 r 發送給 P0,P1。此時,P0,P1 都擁有一個相同的隨機數 r 了。
第三步,設置秘密分享值。
按秘密分享 方案 1 的定義,P0 本地設置 x0 = x - r,P1 本地設置 x1 = r。所以有:
P0:x0 = 4f020 - fdad72ecbfbefeb9 = 2528d134045f167
P1:x1 = fdad72ecbfbefeb9
4f020 是 323616 的十六進制表示。
如果計算結果大于 64 bit 的空間范圍,需要對結果取模(64 位空間)。下同。
至此,我們獲得了關于 x 的分享值,share(x) = (x0, x1) = (x - r, r) = (2528d134045f167, fdad72ecbfbefeb9)。
感興趣的讀者朋友可以驗證一下 (x0 + x1) mod 264264 。
同理,我們對 Bob 的輸入值進行一樣的處理。
上面三步,其實就是 private_console_input 的工作機制與過程。經過處理后,各方本地都存儲著如下值:
我們用 Xi,Yi 表示 X,Y 在 Pi 的分享值。(下同)
P2 為何是 0 呢?在本方案中 P2 作為一個輔助節點,不參與真正的邏輯計算。
我們可以看到,在處理隱私數據輸入的整個過程中,P0 無法知道 y 值,P1 無法知道 x 值,P2 無法知道 x 或 y 值。
最后,我們總結一下這三個主要階段:
密文上的協同計算
這是計算的核心。
上一步,我們保證了輸入的安全,沒有信息的泄漏,各方無法單獨拿到其他節點的私有輸入。
接下來,看一下計算的代碼,只有一行:
z = tf.multiply(x, y) # z = x * y在這個計算的過程中發生了什么?下面結合乘法(Multiply) 算子原理進行實例講解。
Multiply 算子原理
乘法相對較為復雜,我們結合經典的 Beaver Triple 方法 [2] 加以介紹。該方法是由密碼學家 Donald Beaver 在 1991 年提出,主要思想是通過乘法。協議基本原理如下:
輸入: P0 擁有 X,Y 的秘密分享值 X0,Y0;P1 擁有 X,Y 的秘密分享值 X1,Y1。
這里有 share(X) = (X0, X1),share(Y) = (Y0, Y1)。在此案例中,這里的輸入,就對接上一節所述的"隱私輸入"的輸出結果。
計算步驟:
A,B,C 的生成步驟:P2 隨機生成 A0,A1,B0,B1,C0,令 A = A0 + A1, B = B0 + B1,得到 C = A * B, C1 = C - C0。其中 Ai,Bi,Ci 是 A,B,C 的分享值。 這些都是在 P2 本地完成的。這也就是 P2 做為輔助節點的作用(用于隨機數生成)。
這里 A,B,C 一般被稱為三元組(Beaver’s Triple)。
比如,某次生成的隨機數如下:
感興趣的讀者朋友可以驗證一下。如 A = A0 + A1 = 2373edde1a0e5dcd + ad483b77e4e5db41 = d0bc2955fef4390e。這個 A 是個隨機數。
即將 A0,B0,C0 發送給 P0;將 A1,B1,C1 發送給 P1。
此時,P0,P1 擁有如下值:
P0 本地計算 E0 = X0 - A0, F0 = Y0 - B0。
P1 本地計算 E1 = X1 - A1, F1 = Y1 - B1。
此時,P0,P1 擁有如下值:
交換 Ei,Fi。
P0 將 E0,F0 發送給 P1;P1 將 E1,F1 發送給 P0。此時,P0,P1 都擁有 E0,F0,E1,F1。
P0,P1 各自本地計算 E = E0 + E1, F = F0 + F1。
現在,P0 已經擁有 A0,B0,C0,E,F;P1 已經擁有 A1,B1,C1,E,F。有了這些就可以計算出 Z = X * Y 的秘密分享值 Z0,Z1 了。 即:
P0 本地計算 Z0 = E * B0 + A0 * F + C0;
P1 本地計算 Z1 = E * B1 + A1 * F + C1 + E * F。
正確性可以通過以下恒等式加以驗證:
Z=Z0+Z1 =E?B0+A0?F+C0+E?B1+A1?F+C1+E?F
=E?(B0+B1)+(A0+A1)?F+(C0+C1)+E?F
=E?B+A?F+C+E?F =E?B+A?F+A?B+E?F
=(A+E)?(B+F) =(A+X?A)?(B+Y?B)=X?Y Z
=Z0+Z1
=E?B0+A0?F+C0+E?B1+A1?F+C1+E?F
=E?(B0+B1)+(A0+A1)?F+(C0+C1)+E?F
=E?B+A?F+C+E?F
=E?B+A?F+A?B+E?F
=(A+E)?(B+F)
=(A+X?A)?(B+Y?B)=X?Y
輸出: P0,P1 分別持有 Z = X * Y 的秘密分享值 Z0,Z1。
我們可以看到,從輸入到計算再到輸出,整個過程中,沒有泄漏任何隱私數據。
整個算子計算結束時, P0 單獨擁有 X0,Y0,A0,B0,C0,E0,F0,E1,F1,E,F,Z0,P1 單獨擁有 X1,Y1,A1,B1,C1,E0,F0,E1,F1,E,F,Z1,P2 單獨擁有 A0,B0,C0,A1,B1,C1,三方都無法單獨得到 X 或 Y 或 Z。
最后,我們總結一下(1~5 對應著上面的步驟):
獲取明文結果
從輸入到計算再到輸出,各節點只能看到本地所單獨擁有的秘密分享值(一些毫無規律的 64 位隨機數),從上文也可以看到,節點是無法獨自得到任何隱私數據的。那么,當計算結束后,如果想得到結果的明文,怎么獲取呢?
Rosetta 提供了一個恢復明文的接口,使用很簡單。
res = sess.run(rtt.SecureReveal(z, receive_party=4)) # 'b0100' means Charleyprint('z:', res)那這個 rtt.SecureReveal 是如何工作的呢?
其實非常簡單:如果本方想要知道明文,只需要對方把他的秘密分享值發給我,然后本地相加即可。
比如,上一節結尾處,我們知道了各方 (P0/P1/P2) 的分享值如下:
結合實例,Charley (P2) 想要獲取結果明文,那么,P0,P1 將各自的分享值 Z0,Z1 發給 P2,然后 P2 本地相加即可。即: 1db35d14c12a + ffffe24ca30611b0 = 1ad2da (1757914)。我們將此值進一步再轉換為浮點數,就可以得到我們想要的用戶態的明文值了: 1757914 / (1 << 18)= 6.7059097 !
效率優化
上面介紹的 秘密分享 與 multiply 算子 都是基于最基本的算法原理,在時間上和通信上的開銷還是比較大的,在實際工程實現中,還可以進一步進行優化以提升性能。在介紹優化方案之前,先了解一下 什么是 PRF?
PRF[3],Pseudo-Random Function。 簡單來說,即給定一個隨機種子 key,一個計數器 counter,執行 PRF(key, counter) ,會得到一個相同的隨機數。
補充說明一下。例如,P0,P1 執行 PRF(key01, counter01),會產生一個相同的隨機數。這里的 key01,counter01 對于 P0,P1 來說是一致的。程序會維護這兩個值,對使用者來說是透明的。
關于秘密分享
來看看優化版本(假設: P0 有一個私有數據 x)。
- 方案 2(優化版): P0,P1 使用 PRF(key01, counter) 本地同時生成一個相同的隨機數 r。然后 P0 本地設置 x0 = x - r,P1 本地設置 x1 = r。此時 share(x) = (x0, x1) = (x - r, r),與定義一致。此版本無需 P2 的參與。沒有通信開銷。
目前 Rosetta 開源版本中使用的正是此方案。
- 方案 3(優化版): P0 設置 x0 = x,P1 設置 x1 = 0 即可。此時 share(x) = (x, 0)。此版本無需 P2 的參與。沒有通信開銷,也沒有計算開銷。
上述各個版本(包括方案 1),都是可行且安全的。可以看到P1/P2 并不知道 P0 的原始輸入值。
關于 Multiply 算子
Multiply 算子中輸入,輸出部分沒有變化,主要是計算步驟中的第 1 步與第 2 步有些許變化,以減少通信量。這里也只描述這兩步,其余與前文相同。
在上文的描述中,我們知道 P2 生成三元組后,需要將其分享值發送給 P0,P1。當我們有了 PRF 后,可以這么做:
相比于原始版本,優化版本只需要發送 C1,不用再發送 A0,A1,B0,B1,C0。
在 Rosetta 中,我們還針對具體的各個不同的算子進行了一系列的算法、工程優化,歡迎感興趣的讀者來進一步了解。
小結
安全性是隱私 AI 框架的根本,在本篇文章中,我們結合隱私數據輸入的處理和密文上乘法的實現,介紹了“隨機數” 形式的密文是如何在多方之間流動,同時“神奇”的仍能保證計算邏輯的正確性的。我們這里對于安全性的說明是直觀上的描述,而實際上,這些算法的安全性都是有嚴格數學證明的。感興趣的讀者可以進一步去探索相關的論文。
Rosetta 將持續集成安全可靠的密碼學算法協議作為“隱私計算引擎”到框架后端中,也歡迎廣大開發者參與到隱私 AI 的生態建設中來。
參考文獻
[1] 秘密共享, https://en.wikipedia.org/wiki/Secret_sharing
[2] Beaver, Donald. “Efficient multiparty protocols using circuit randomization.” Annual International Cryptology Conference. Springer, Berlin, Heidelberg, 1991.
[3] PRF 的一個簡單介紹, https://crypto.stanford.edu/pbc/notes/crypto/prf.html
作者介紹:
Rosetta 技術團隊,一群專注于技術、玩轉算法、追求高效的工程師。Rosetta 是一款基于主流深度學習框架 TensorFlow 的隱私 AI 框架,作為矩陣元公司大規模商業落地的重要引擎,它承載和結合了隱私計算、區塊鏈和 AI 三種典型技術。目前 Rosetta 已經在 Github 開源( https://github.com/LatticeX-Foundation/Rosetta) ,歡迎關注并參與到 Rosetta 社區中來。
延伸閱讀:
隱私AI工程技術實踐指南:整體介紹-InfoQ
面向隱私AI的TensorFlow深度定制化實踐-InfoQ
隱私AI框架中MPC協議的快速集成-InfoQ
關注我并轉發此篇文章,私信我“領取資料”,即可免費獲得InfoQ價值4999元迷你書,點擊文末「了解更多」,即可移步InfoQ官網,獲取最新資訊~
總結
以上是生活随笔為你收集整理的ai算子是什么_隐私AI框架中的数据流动与工程实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: eclipse的tomcat如何运行自动
- 下一篇: cf活动金银蛇戒,你最喜欢他们哪项属性?