*本文做者系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联系咱们,投递简历请注明:联邦学习职位。