譯者 | 布加迪
審校 | 重樓
在云計(jì)算和基于機(jī)器學(xué)習(xí)的服務(wù)唾手可得的時(shí)代,隱私是一大挑戰(zhàn)。將端到端隱私添加到協(xié)作式機(jī)器學(xué)習(xí)用例聽起來像是一項(xiàng)艱巨的任務(wù)。幸好,諸如完全同態(tài)加密(FHE)之類的密碼學(xué)突破提供了解決方案。Zama的新演示展示了如何利用開源機(jī)器學(xué)習(xí)工具使用聯(lián)合學(xué)習(xí)和FHE來添加端到端隱私。這篇博文解釋了這番演示的底層工作機(jī)理,結(jié)合了scikit-learn、聯(lián)合學(xué)習(xí)和FHE。
FHE這種技術(shù)使應(yīng)用程序提供方能夠構(gòu)建基于云的應(yīng)用程序以保護(hù)用戶隱私,而Concrete ML這種機(jī)器學(xué)習(xí)工具包可以讓模型改而使用FHE。Concrete ML利用了scikit-learn中強(qiáng)大穩(wěn)健的模型訓(xùn)練算法來訓(xùn)練與FHE兼容的模型,無需任何密碼學(xué)知識(shí)。
Concrete ML使用scikit-learn作為構(gòu)建與FHE兼容的模型的基礎(chǔ),這是由于scikit-learn擁有出色的易用性、可擴(kuò)展性、健壯性以及用于構(gòu)建、驗(yàn)證和調(diào)整數(shù)據(jù)管道的眾多工具。雖然深度學(xué)習(xí)在非結(jié)構(gòu)化數(shù)據(jù)上表現(xiàn)良好,但它通常需要超參數(shù)調(diào)優(yōu)才能達(dá)到高精度。在許多用例中,特別是針對(duì)結(jié)構(gòu)化數(shù)據(jù),scikit-learn憑借其訓(xùn)練算法的穩(wěn)健性表現(xiàn)出色。
本地訓(xùn)練模型,并安全地部署
當(dāng)數(shù)據(jù)科學(xué)家擁有所有訓(xùn)練數(shù)據(jù)時(shí),訓(xùn)練很安全,因?yàn)闆]有數(shù)據(jù)離開機(jī)器,并且在部署模型時(shí)只需要確保推理安全。然而,用FHE保護(hù)的推理的訓(xùn)練模型對(duì)模型訓(xùn)練實(shí)施了一定的限制。雖然過去使用FHE需要密碼學(xué)專業(yè)知識(shí),但像Concrete ML這樣的工具將密碼學(xué)這部分屏蔽起來,使數(shù)據(jù)科學(xué)家可以享用FHE。此外,F(xiàn)HE增加了計(jì)算開銷,這意味著機(jī)器學(xué)習(xí)模型可能需要針對(duì)準(zhǔn)確性和運(yùn)行時(shí)延遲進(jìn)行調(diào)整。Concrete ML使用scikit-learn實(shí)用程序類(比如GridSearchCV)充分利用參數(shù)搜索,從而使這種調(diào)整變得很容易。
若使用Concrete ML本地訓(xùn)練模型,語法對(duì)scikit-learn來說一樣,可以在視頻教程中找到解釋。如果是MNIST上的邏輯回歸模型,只需運(yùn)行以下代碼片段:
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
mnist_dataset = fetch_openml("mnist_784")
x_train, x_test, y_train, y_test = train_test_split(
mnist_dataset.data,
mnist_dataset.target.astype("int"),
test_size=10000,
)
接下來,擬合Concrete ML邏輯回歸模型,該模型是scikit-learn等效模型的臨時(shí)替代品。只需要一個(gè)額外的步驟:編譯,就可以生成對(duì)加密數(shù)據(jù)執(zhí)行推理的FHE計(jì)算電路。編譯由Concrete完成,它是將程序變成FHE等效程序的過程,直接處理加密后的數(shù)據(jù)。
from concrete.ml.sklearn.linear_model import LogisticRegression
model = LogisticRegression(penalty="l2")
model.fit(X=x_train, y=y_train)
model.compile(x_train)
現(xiàn)在測(cè)試模型針對(duì)加密數(shù)據(jù)執(zhí)行時(shí)的準(zhǔn)確性。該模型的準(zhǔn)確率約為92%。與scikit-learn一樣,Concrete ML支持其他許多線性模型,比如SVM、Lasso和ElasticNet,你通過簡(jiǎn)單地更改模型類就可以使用它們。此外,還支持等效scikit-learn模型的所有超參數(shù)(如上面代碼片段中的penalty)。
from sklearn.metrics import accuracy_score
y_preds_clear = model.predict(x_test, fhe="execute")
print(f"The test accuracy of the model on encrypted data {accuracy_score(y_test, y_preds_clear):.2f}")
用于訓(xùn)練數(shù)據(jù)隱私的聯(lián)合學(xué)習(xí)
通常,在有許多用戶的生產(chǎn)系統(tǒng)中,機(jī)器學(xué)習(xí)模型需要針對(duì)所有用戶數(shù)據(jù)的集合進(jìn)行訓(xùn)練,同時(shí)保留每個(gè)用戶的隱私。這種場(chǎng)景下的常見用例包括數(shù)字健康、垃圾郵件檢測(cè)、在線廣告,甚至更簡(jiǎn)單的用例,比如下一個(gè)單詞預(yù)測(cè)輔助。
Concrete ML可以導(dǎo)入由Flower等工具使用聯(lián)合學(xué)習(xí)(FL)訓(xùn)練的模型。要使用FL訓(xùn)練與上述相同的模型,必須定義一個(gè)客戶端應(yīng)用程序和服務(wù)器應(yīng)用程序。首先,客戶端由partition_id標(biāo)識(shí),partition_id是一個(gè)介于0和客戶端數(shù)量之間的數(shù)字。要分割MNIST數(shù)據(jù)集并獲得當(dāng)前客戶端的切片,應(yīng)使用Flower federated_utils軟件包。
(X_train, y_train) = federated_utils.partition(X_train, y_train, 10)[partition_id]
現(xiàn)在定義訓(xùn)練客戶端邏輯:
import flwr as fl
from sklearn.linear_model import LogisticRegression
# Create LogisticRegression Model
model = LogisticRegression(
penalty="l2",
warm_start=True, # prevent refreshing weights when fitting
)
federated_utils.set_initial_params(model)
class MnistClient(fl.client.NumPyClient):
def get_parameters(self, config): # type: ignore
return federated_utils.get_model_parameters(model)
def fit(self, parameters, config): # type: ignore
federated_utils.set_model_params(model, parameters)
model.fit(X_train, y_train)
print(f"Training finished for round {config['server_round']}")
return federated_utils.get_model_parameters(model), len(X_train), {}
def evaluate(self, parameters, config): # type: ignore
federated_utils.set_model_params(model, parameters)
loss = log_loss(y_test, model.predict_proba(X_test))
accuracy = model.score(X_test, y_test)
return loss, len(X_test), {"accuracy": accuracy}
# Start Flower client
fl.client.start_numpy_client(
server_address="0.0.0.0:8080",
client=MnistClient()
)
最后,必須創(chuàng)建一個(gè)典型的Flower服務(wù)器實(shí)例:
model = LogisticRegression()
federated_utils.set_initial_params(model)
strategy = fl.server.strategy.FedAvg()
fl.server.start_server(
server_address="0.0.0.0:8080",
strategy=strategy,
config=fl.server.ServerConfig(num_rounds=5),
)
訓(xùn)練停止后,客戶端或服務(wù)器可以將模型存儲(chǔ)到文件中:
with open("model.pkl", "wb") as file:
pickle.dump(model, file)
一旦模型得到訓(xùn)練,就可以從pickle文件中加載它,并將其轉(zhuǎn)換成Concrete ML模型,以啟用保護(hù)隱私的推理。實(shí)際上,Concrete ML既可以訓(xùn)練新模型(如上文所示),也可以轉(zhuǎn)換現(xiàn)有模型(比如FL創(chuàng)建的模型)。使用from_sklearn_model函數(shù)的這個(gè)轉(zhuǎn)換步驟在下面用于使用聯(lián)合學(xué)習(xí)訓(xùn)練的模型上。該視頻進(jìn)一步解釋了如何使用該函數(shù)。
with path_to_model.open("rb") as file:
sklearn_model = pickle.load(file)
compile_set = numpy.random.randint(0, 255, (100, 784)).astype(float)
sklearn_model.classes_ = sklearn_model.classes_.astype(int)
from concrete.ml.sklearn.linear_model import LogisticRegression
model = LogisticRegression.from_sklearn_model(sklearn_model, compile_set)
model.compile(compile_set)
至于本地訓(xùn)練,使用一些測(cè)試數(shù)據(jù)評(píng)估該模型:
from sklearn.metrics import accuracy_score
y_preds_enc = model.predict(x_test, fhe="execute")
print(f"The test accuracy of the model on encrypted data {accuracy_score(y_test, y_preds_enc):.2f}")
總之,使用scikit-learn、Flower和Concrete ML,只需要幾行代碼,就可以以完全保護(hù)隱私的方式訓(xùn)練模型并預(yù)測(cè)新數(shù)據(jù):數(shù)據(jù)集片段是保密的,預(yù)測(cè)針對(duì)加密數(shù)據(jù)執(zhí)行。這里訓(xùn)練的模型針對(duì)加密數(shù)據(jù)執(zhí)行時(shí)達(dá)到了92%的準(zhǔn)確率。
結(jié)論
上面討論了基于Flower和Concrete ML的完整端到端專有訓(xùn)練演示的最重要步驟。你可以在我們的開源代碼存儲(chǔ)庫中找到所有源代碼。與scikit-learn兼容使Concrete ML的用戶能夠使用熟悉的編程模式,并便于與scikit-learn兼容的工具包(比如Flower)兼容。本文中的示例僅對(duì)原始scikit-learn管道進(jìn)行了一些更改,表明了如何使用聯(lián)合學(xué)習(xí)和FHE為使用MNIST訓(xùn)練分類器增添端到端隱私。
原文標(biāo)題:End-to-end privacy for model training and inference with Concrete ML。