在 Hugging Face 端點上執行隱私保護推理
這是 Zama 團隊的客座部落格文章。Zama 是一家開源密碼學公司,致力於為區塊鏈和人工智慧構建最先進的 FHE 解決方案。
十八個月前,Zama 啟動了 Concrete ML,這是一個隱私保護機器學習框架,與 scikit-learn、ONNX、PyTorch 和 TensorFlow 等傳統機器學習框架繫結。為了確保使用者資料的隱私,Zama 使用了全同態加密 (FHE),這是一種允許直接對加密資料進行計算而無需知道私鑰的加密工具。
從一開始,我們就希望預編譯一些 FHE 友好型網路並將它們釋出到網際網路上,讓使用者可以輕鬆使用它們。我們今天已經準備好了!而且不是在網際網路上的某個隨機位置,而是直接在 Hugging Face 上。
更準確地說,我們使用 Hugging Face 端點和 自定義推理處理器,以便能夠儲存我們的 Concrete ML 模型,並讓使用者一鍵部署到 Hugging Face 機器上。在本篇部落格文章的末尾,您將瞭解如何使用預編譯模型以及如何準備自己的模型。這篇部落格文章也可以被視為自定義推理處理器的另一個教程。
部署預編譯模型
讓我們從部署一個 FHE 友好型模型開始(由 Zama 或第三方準備——有關如何準備自己的模型,請參見下面的 準備您的預編譯模型 部分)。
首先,尋找您想要部署的模型:我們在 Zama 的 HF 頁面上預編譯了大量模型(或者您可以透過標籤找到它們)。假設您選擇了 concrete-ml-encrypted-decisiontree:如描述中所述,此預編譯模型允許您在不檢視明文訊息內容的情況下檢測垃圾郵件。
與 Hugging Face 平臺上的其他任何模型一樣,選擇 部署,然後選擇 推理端點(專用)。
接下來,選擇端點名稱或區域,最重要的是,選擇 CPU(Concrete ML 模型目前不使用 GPU;我們正在努力解決這個問題)以及可用的最佳機器——在下面的示例中,我們選擇了八個 vCPU。現在點選 建立端點 並等待初始化完成。
幾秒鐘後,端點部署完畢,您的隱私保護模型即可執行。
:當您不再使用端點時,不要忘記刪除它(或至少暫停它),否則費用會超出預期。
使用端點
安裝客戶端
目標不僅是部署您的端點,還要讓您的使用者使用它。為此,他們需要在自己的計算機上克隆倉庫。這可以透過在下拉選單中選擇 克隆倉庫 來完成。
他們將獲得一個簡短的命令列,可以在終端中執行。
git clone https://huggingface.co/zama-fhe/concrete-ml-encrypted-decisiontree
命令執行完畢後,他們進入 concrete-ml-encrypted-decisiontree
目錄,並用編輯器開啟 play_with_endpoint.py
。在這裡,他們會找到 API_URL = …
這一行,並應將其替換為上一節中建立的端點的新 URL。
API_URL = "https://vtx9w974oxrq54ff.us-east-1.aws.endpoints.huggingface.cloud"
當然,請填寫*您的*入口點的 URL。此外,定義一個訪問令牌並將其儲存在環境變數中。
export HF_TOKEN=[your token hf_XX..XX]
最後,您的使用者機器需要本地安裝 Concrete ML:建立一個虛擬環境,啟用它,並安裝必要的依賴項。
python3.10 -m venv .venv
source .venv/bin/activate
pip install -U setuptools pip wheel
pip install -r requirements.txt
請注意,我們目前強制使用 Python 3.10(這也是 Hugging Face Endpoints 中使用的預設 Python 版本)。這是因為我們的開發檔案目前依賴於 Python 版本。我們正在努力使其獨立。這應該在後續版本中提供。
執行推理
現在,您的使用者可以透過執行指令碼在端點上執行推理。
python play_with_endpoint.py
它應該生成一些類似於以下內容的日誌:
Sending 0-th piece of the key (remaining size is 71984.14 kbytes)
Storing the key in the database under uid=3307376977
Sending 1-th piece of the key (remaining size is 0.02 kbytes)
Size of the payload: 0.23 kilobytes
for 0-th input, prediction=0 with expected 0 in 3.242 seconds
for 1-th input, prediction=0 with expected 0 in 3.612 seconds
for 2-th input, prediction=0 with expected 0 in 4.765 seconds
(...)
for 688-th input, prediction=0 with expected 1 in 3.176 seconds
for 689-th input, prediction=1 with expected 1 in 4.027 seconds
for 690-th input, prediction=0 with expected 0 in 4.329 seconds
Accuracy on 691 samples is 0.8958031837916064
Total time: 2873.860 seconds
Duration per inference: 4.123 seconds
適應您的應用程式或需求
如果您編輯 play_with_endpoint.py
,您會看到我們遍歷了測試資料集的不同樣本,並直接在端點上執行加密推理。
for i in range(nb_samples):
# Quantize the input and encrypt it
encrypted_inputs = fhemodel_client.quantize_encrypt_serialize(X_test[i].reshape(1, -1))
# Prepare the payload
payload = {
"inputs": "fake",
"encrypted_inputs": to_json(encrypted_inputs),
"method": "inference",
"uid": uid,
}
if is_first:
print(f"Size of the payload: {sys.getsizeof(payload) / 1024:.2f} kilobytes")
is_first = False
# Run the inference on HF servers
duration -= time.time()
duration_inference = -time.time()
encrypted_prediction = query(payload)
duration += time.time()
duration_inference += time.time()
encrypted_prediction = from_json(encrypted_prediction)
# Decrypt the result and dequantize
prediction_proba = fhemodel_client.deserialize_decrypt_dequantize(encrypted_prediction)[0]
prediction = np.argmax(prediction_proba)
if verbose:
print(
f"for {i}-th input, {prediction=} with expected {Y_test[i]} in {duration_inference:.3f} seconds"
)
# Measure accuracy
nb_good += Y_test[i] == prediction
當然,這只是一個入口點使用的示例。鼓勵開發人員根據自己的用例或應用程式調整此示例。
幕後工作
請注意,所有這些都得益於自定義處理程式的靈活性,我們對 Hugging Face 開發人員提供如此靈活性表示感謝。其機制在 handler.py
中定義。如 Hugging Face 文件中所述,您可以根據需要定義 EndpointHandler
的 __call__
方法:在我們的案例中,我們定義了一個 method
引數,它可以是 save_key
(用於儲存 FHE 評估金鑰)、append_key
(如果金鑰太大無法一次性發送,則分段儲存 FHE 評估金鑰)以及最終的 inference
(用於執行 FHE 推理)。這些方法用於一次設定評估金鑰,然後逐個執行所有推理,如 play_with_endpoint.py
中所示。
限制
然而,人們可能會發現金鑰儲存在端點的 RAM 中,這對於生產環境來說並不方便:每次重啟,金鑰都會丟失,需要重新發送。此外,當您有多臺機器來處理大量流量時,這種 RAM 不會在機器之間共享。最後,可用的 CPU 機器最多隻能為端點提供八個 vCPU,這對於高負載應用程式來說可能是一個限制。
準備您的預編譯模型
既然您知道了部署預編譯模型是多麼容易,您可能想準備自己的模型。為此,您可以克隆我們準備的其中一個倉庫。Concrete ML 支援的所有模型類別(線性模型、基於樹的模型、內建多層感知器、PyTorch模型)都至少有一個示例,可以作為新預編譯模型的模板。
然後,編輯 creating_models.py
,並將機器學習任務更改為您想要在預編譯模型中處理的任務:例如,如果您從 concrete-ml-encrypted-decisiontree 開始,請更改資料集和模型型別。
如前所述,您必須安裝 Concrete ML 才能準備預編譯模型。請注意,您可能需要使用與 Hugging Face 預設使用的 Python 版本相同(編寫本部落格時為 3.10),否則您的模型可能需要人們在部署期間使用帶有您的 Python 的容器。
現在您可以啟動 python creating_models.py
。這將訓練模型並在 compiled_model
目錄中建立必要的開發檔案(client.zip
、server.zip
和 versions.json
)。如文件中所述,這些檔案包含您的預編譯模型。如果您有任何問題,可以在 fhe.org discord 上獲得支援。
最後一步是修改 play_with_endpoint.py
,使其也處理與 creating_models.py
中相同的 ML 任務:相應地設定資料集。
現在,您可以將此目錄以及 compiled_model
目錄和檔案,以及您在 creating_models.py
和 play_with_endpoint.py
中所做的修改儲存到 Hugging Face 模型中。當然,您需要執行一些測試並進行微調才能使其正常工作。不要忘記新增 concrete-ml
和 FHE
標籤,以便您的預編譯模型能夠輕鬆地在搜尋中顯示。
目前可用的預編譯模型
目前,我們已經準備了一些預編譯模型作為示例,希望社群能儘快擴充套件。可以透過搜尋 concrete-ml 或 FHE 標籤來找到預編譯模型。
請記住,Hugging Face 為 CPU 支援的端點提供的配置選項有限(目前最多 8 個 vCPU 和 16 GB RAM)。根據您的生產需求和模型特性,在更強大的雲實例上執行時間可能會更快。希望 Hugging Face 端點很快能提供更強大的機器來改善這些時間。
額外資源
- 檢視 Zama 庫 Concrete 和 Concrete-ML,並開始在您自己的應用程式中使用 FHE。
- 檢視 Zama 的 Hugging Face 個人資料,閱讀更多部落格文章並嘗試實用的 FHE 演示。
- 在 Twitter 上關注 @zama_fhe,獲取我們的最新更新。
結論和下一步
在這篇部落格文章中,我們展示了自定義端點非常容易且功能強大。我們在 Concrete ML 中所做的工作與機器學習從業者的常規工作流程截然不同,但我們仍然能夠適應自定義端點來滿足我們大部分需求。向 Hugging Face 工程師開發如此通用的解決方案致敬。
我們解釋瞭如何
- 開發人員可以建立自己的預編譯模型並將其釋出到 Hugging Face 模型上。
- 公司可以部署開發人員的預編譯模型,並透過 HF 端點提供給使用者。
- 終端使用者可以使用這些端點對加密資料執行機器學習任務。
為了進一步發展,在 Hugging Face 端點上提供更強大的機器以加快推理速度將非常有益。此外,我們可以設想 Concrete ML 更好地整合到 Hugging Face 的介面中,並提供一個“隱私保護推理端點”按鈕,從而進一步簡化開發人員的工作。最後,為了在多個伺服器機器中進行整合,如果有一種方法可以在機器之間共享狀態並保持此狀態非易失(FHE 推理金鑰將儲存在此處),那將非常有幫助。