*本文做者系VMware雲原生實驗室工程師 陳家豪html
概述 在前面的文章中,咱們介紹過如何使用KubeFATE來部署一個單節點的FATE聯邦學習集羣。在真實的應用場景中,聯邦學習每每須要多個參與方聯合起來一塊兒完成任務。基於此,本文將講述如何經過KubeFATE和Docker-Compose來部署兩個參與方的FATE集羣,並在集羣上運行一些簡單的測試以驗證其功能的完整性。node
FATE集羣的組網方式 聯邦學習的訓練任務須要多方參與,如圖1所示,每個party node都是一方,而且每一個party node都有各自的一套FATE集羣。而party node和party node之間的發現方式有兩種。分別是點對點和星型。默認狀況下,使用KubeFATE部署的多方集羣會經過點對點的方式組網,但KubeFATE也能夠單獨部署Exchange服務以支持星型組網。python
圖 1 FATE集羣組網方式git
使用KubeFATE和Docker-Compose部署兩方訓練的集羣github
KubeFATE的使用分紅兩部分,第一部分是生成FATE集羣的啓動文件(docker-compose.yaml),第二個部分是經過docker-compose的方式去啓動FATE集羣。從邏輯上可將進行這兩部分工做的機器分別稱爲部署機和目標機器。 Figure 1部署機目標機關係圖面試
目標 兩個能夠互通的FATE實例,每一個實例均包括FATE全部組件,實例分別部署在不一樣的兩臺機器上。docker
準備工做編程
- 兩個主機(物理機或者虛擬機,Ubuntu或Centos7系統,容許以root用戶登陸);
- 全部主機安裝Docker 版本 : 18+;
- 全部主機安裝Docker-Compose 版本: 1.24+;
- 部署機能夠聯網,因此主機相互之間能夠網絡互通;
- 運行機已經下載FATE 的各組件鏡像
Docker的安裝以及FATE鏡像的下載請參考前文,接下來咱們將把兩臺主機劃分爲workspace1和workspace2。其中workspace1既做爲部署機也做爲目標機,而workspace2則做爲目標機,每一個機器運行一個FATE實例。這裏兩臺主機的IP分別爲192.168.7.1和192.168.7.2。用戶須要根據實際狀況作出修改。具體部署架構如圖2所示。 圖 2部署架構圖json
如下操做需在workspace1上並以root用戶進行。bash
下載並解壓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」(https://www.kaggle.com/yuqing01/breast-cancer),其中」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>/
在此插播一條招聘廣告,歡迎你們踊躍投遞簡歷!
爲更好的開發聯邦學習的開源項目,VMware中國研發中心現招聘實習生若干名(北京或上海),最好熟悉機器學習框架或平臺,掌握一門現代編程語言,以Python,Golang優先考慮!
職位要求:
-
計算機科學或相近專業在讀研究生
-
熟悉至少一門現代編程語言,如 Go, Python, Java, C++
-
有云原生技術,如容器,K8s等的項目經驗優先具備機器學習方面經驗者優先,FATE社區參與者可直接進入面試
-
熟悉開源軟件社區運做,參與過開源項目貢獻者優先
投遞簡歷或諮詢與KubeFATE相關問題可經過 kubefate@vmware.com聯繫咱們,投遞簡歷請註明:聯邦學習職位。