在前面的文章中,我們介紹過如何使用KubeFATE來部署一個單節點的FATE聯邦學習集羣。在真實的應用場景中,聯邦學習往往需要多個參與方聯合起來一起完成任務。基於此,本文將講述如何通過KubeFATE和Docker-Compose來部署兩個參與方的FATE集羣,並在集羣上運行一些簡單的測試以驗證其功能的完整性。
FATE集羣的組網方式
聯邦學習的訓練任務需要多方參與,如圖1所示,每一個party node都是一方,並且每個party node都有各自的一套FATE集羣。而party node和party node之間的發現方式有兩種。分別是點對點和星型。默認情況下,使用KubeFATE部署的多方集羣會通過點對點的方式組網,但KubeFATE也可以單獨部署Exchange服務以支持星型組網。
部署兩方訓練的集羣
使用KubeFATE和Docker-Compose部署兩方訓練的集羣
KubeFATE的使用分成兩部分,第一部分是生成FATE集羣的啓動文件(docker-compose.yaml),第二個部分是通過docker-compose的方式去啓動FATE集羣。從邏輯上可將進行這兩部分工作的機器分別稱爲部署機和目標機器。
目標
兩個可以互通的FATE實例,每個實例均包括FATE所有組件,實例分別部署在不同的兩臺機器上。
準備工作
1、兩個主機(物理機或者虛擬機,Ubuntu或Centos7系統,允許以root用戶登錄);
2、所有主機安裝Docker 版本 : 18+;
3、所有主機安裝Docker-Compose 版本: 1.24+;
4、部署機可以聯網,所以主機相互之間可以網絡互通;
5、運行機已經下載FATE 的各組件鏡像
Docker的安裝以及FATE鏡像的下載請參考前文,接下來我們將把兩臺主機劃分爲workspace1和workspace2。其中workspace1既作爲部署機也作爲目標機,而workspace2則作爲目標機,每個機器運行一個FATE實例。這裏兩臺主機的IP分別爲192.168.7.1和192.168.7.2。用戶需要根據實際情況做出修改。具體部署架構如圖2所示。
以下操作需在workspace1上並以root用戶進行。
下載並解壓Kubefate1.3的kubefate-docker-compose.tar.gz資源包
# curl -OL
https://github.com/FederatedAI/KubeFATE/releases/download/v1.3.0/kubefate-docker-compose.tar.gz
# tar -xzf kubefate-docker-compose.tar.gz
定義需要部署的實例數目
進入docker-deploy目錄
# cd docker-deploy/
編輯parties.conf如下
# vi parties.conf
user=root
dir=/data/projects/fate
partylist=(10000 9999)
partyiplist=(192.168.7.1 192.168.7.2)
servingiplist=(192.168.7.1 192.168.7.2)
exchangeip=
根據以上定義party 10000的集羣將部署在workspace1上,而party 9999的集羣將部署在workspace2上。
執行生成集羣啓動文件腳本
# bash generate_config.sh
執行啓動集羣腳本
# bash docker_deploy.sh all
命令輸入後需要用戶輸入4次root用戶的密碼
驗證集羣基本功能
# docker exec -it confs-10000_python_1 bash
# cd /data/projects/fate/python/examples/toy_example
# python run_toy_example.py 10000 9999 1
如果測試通過,屏幕將顯示類似如下消息:
"2019-08-29 07:21:25,353 - secure_add_guest.py[line:96] - INFO: begin to init parameters of secure add example guest"
"2019-08-29 07:21:25,354 - secure_add_guest.py[line:99] - INFO: begin to make guest data"
"2019-08-29 07:21:26,225 - secure_add_guest.py[line:102] - INFO: split data into two random parts"
"2019-08-29 07:21:29,140 - secure_add_guest.py[line:105] - INFO: share one random part data to host"
"2019-08-29 07:21:29,237 - secure_add_guest.py[line:108] - INFO: get share of one random part data from host"
"2019-08-29 07:21:33,073 - secure_add_guest.py[line:111] - INFO: begin to get sum of guest and host"
"2019-08-29 07:21:33,920 - secure_add_guest.py[line:114] - INFO: receive host sum from guest"
"2019-08-29 07:21:34,118 - secure_add_guest.py[line:121] - INFO: success to calculate secure_sum, it is 2000.0000000000002"
驗證Serving-Service功能
以下內容將會對部署好的兩個FATE集羣進行簡單的訓練和推理測試。訓練所用到的數據集是”breast”,其中”breast”按列分爲”breast_a”和”breast_b”兩部分,參與訓練的host方持有”breast_a”,而guest方則持有”breast_b”。guest和host將聯合起來對數據集進行一個異構的邏輯迴歸訓練。最後當訓練完成後還會將得到的模型推送到FATE Serving作在線推理。
以下操作在workspace1上進行:
進入python容器
# docker exec -it confs-10000_python_1 bash
進入fate_flow目錄
# cd fate_flow
修改examples/upload_host.json
# vi examples/upload_host.json
{
"file": "examples/data/breast_a.csv",
"head": 1,
"partition": 10,
"work_mode": 1,
"namespace": "fate_flow_test_breast",
"table_name": "breast"
}
把“breast_a.csv”上傳到系統中
# python fate_flow_client.py -f upload -c examples/upload_host.json
以下操作在workspace2上進行:
進入python容器
# docker exec -it confs-9999_python_1 bash
進入fate_flow目錄
# cd fate_flow
修改examples/upload_guest.json
# vi examples/upload_guest.json
{
"file": "examples/data/breast_b.csv",
"head": 1,
"partition": 10,
"work_mode": 1,
"namespace": "fate_flow_test_breast",
"table_name": "breast"
}
把“breast_b.csv”上傳到系統中
# python fate_flow_client.py -f upload -c examples/upload_guest.json
修改examples/test_hetero_lr_job_conf.json
# vi examples/test_hetero_lr_job_conf.json
{
"initiator": {
"role": "guest",
"party_id": 9999
},
"job_parameters": {
"work_mode": 1
},
"role": {
"guest": [9999],
"host": [10000],
"arbiter": [10000]
},
"role_parameters": {
"guest": {
"args": {
"data": {
"train_data": [{"name": "breast", "namespace": "fate_flow_test_breast"}]
}
},
"dataio_0":{
"with_label": [true],
"label_name": ["y"],
"label_type": ["int"],
"output_format": ["dense"]
}
},
"host": {
"args": {
"data": {
"train_data": [{"name": "breast", "namespace": "fate_flow_test_breast"}]
}
},
"dataio_0":{
"with_label": [false],
"output_format": ["dense"]
}
}
},
....
}
提交任務對上傳的數據集進行訓練
# python fate_flow_client.py -f submit_job -d examples/test_hetero_lr_job_dsl.json -c examples/test_hetero_lr_job_conf.json
輸出結果:
{
"data": {
"board_url": "http://fateboard:8080/index.html#/dashboard?job_id=202003060553168191842&role=guest&party_id=9999",
"job_dsl_path": "/data/projects/fate/python/jobs/202003060553168191842/job_dsl.json",
"job_runtime_conf_path": "/data/projects/fate/python/jobs/202003060553168191842/job_runtime_conf.json",
"logs_directory": "/data/projects/fate/python/logs/202003060553168191842",
"model_info": {
"model_id": "arbiter-10000#guest-9999#host-10000#model",
"model_version": "202003060553168191842"
}
},
"jobId": "202003060553168191842",
"retcode": 0,
"retmsg": "success"
}
訓練好的模型會存儲在EGG節點中,模型可通過在上述輸出中的“model_id” 和 “model_version” 來定位。FATE Serving的加載和綁定模型操作都需要用戶提供這兩個值。
查看任務狀態直到”f_status”爲success,把上一步中輸出的“jobId”方在“-j”後面。
# python fate_flow_client.py -f query_task -j 202003060553168191842 | grep f_status
output:
"f_status": "success",
"f_status": "success",
修改加載模型的配置,把上一步中輸出的“model_id”和“model_version”與文件中的進行替換。
# vi examples/publish_load_model.json
{
"initiator": {
"party_id": "9999",
"role": "guest"
},
"role": {
"guest": ["9999"],
"host": ["10000"],
"arbiter": ["10000"]
},
"job_parameters": {
"work_mode": 1,
"model_id": "arbiter-10000#guest-9999#host-10000#model",
"model_version": "202003060553168191842"
}
}
加載模型
# python fate_flow_client.py -f load -c examples/publish_load_model.json
修改綁定模型的配置, 替換“model_id”和“model_version”,並給“service_id”賦值“test”。其中“service_id”是推理服務的標識,該標識與一個模型關聯。用戶向FATE Serving發送請求時需要帶上“service_id”,這樣FATE Serving纔會知道用哪個模型處理用戶的推理請求。
# vi examples/bind_model_service.json
{
"service_id": "test",
"initiator": {
"party_id": "9999",
"role": "guest"
},
"role": {
"guest": ["9999"],
"host": ["10000"],
"arbiter": ["10000"]
},
"job_parameters": {
"work_mode": 1,
"model_id": "arbiter-10000#guest-9999#host-10000#model",
"model_version": "202003060553168191842"
}
}
綁定模型
# python fate_flow_client.py -f bind -c examples/bind_model_service.json
在線測試,通過curl發送以下信息到192.168.7.2:8059/federation/v1/inference
curl -X POST -H 'Content-Type: application/json' -d ' {"head":{"serviceId":"test"},"body":{"featureData": {"x0": 0.254879,"x1": -1.046633,"x2": 0.209656,"x3": 0.074214,"x4": -0.441366,"x5": -0.377645,"x6": -0.485934,"x7": 0.347072,"x8": -0.287570,"x9": -0.733474}}' 'http://192.168.7.2:8059/federation/v1/inference'
輸出結果:
{"flag":0,"data":{"prob":0.30684422824464636,"retmsg":"success","retcode":0}
若輸出結果如上所示,則驗證了serving-service的功能是正常的。上述結果說明有以上特徵的人確診概率爲30%左右。
刪除部署
如果需要刪除部署,則在部署機器上運行以下命令可以停止所有FATE集羣:
# bash docker_deploy.sh --delete all
如果想要徹底刪除在運行機器上部署的FATE,可以分別登錄節點,然後運行命令:
# cd /data/projects/fate/confs-<id>/ # the id of party
# docker-compose down
# rm -rf ../confs-<id>/
KubeFATE開源項目:
https://github.com/FederatedAI/KubeFATE
FATE開源項目:
https://github.com/FederatedAI/FATE
作者介紹:
彭路,VMware 雲原生實驗室工程師,FATE/KubeFATE 項目貢獻者。
相關文章: