FATE(Federated AI Technology Enabler)是一個聯邦學習框架,能有效幫助多個機構在滿足用戶隱私保護、數據安全和政府法規的要求下,進行數據使用和建模。但由於其系統的分佈式特性,導致使用存在一定門檻。鑑於此,VMware聯合微衆銀行一起開發了KubeFATE項目,致力於降低FATE的使用門檻和系統運維成本。本文將首先分析FATE的整體架構,幫助讀者理解各部件的作用;然後將展示如何從一臺Linux機器開始,通過KubeFATE一步一步來搭建聯邦學習的實驗環境。
FATE整體架構
一個正常工作的FATE集羣裏面包含了若干組件,其中有些負責任務調度、有些負責存儲,各個組件各司其職,聯合起來一起完成任務。一個FATE集羣所包含的組件如下圖所示。
各個服務的功能描述如下:
- FATE Flow:該服務分爲Client和Server兩部分,其中Client部分由用戶使用,用於向FATE集羣提交聯邦學習任務;FATE Flow Server是FATE集羣對外提供服務的入口,同時它也負責調度、執行用戶提交的任務請求和協調任務參與方。
- MySQL:與任務相關的一些元數據,如創建時間,狀態都會存在MySQL中。
- EGG/ROLL:向訓練任務提供了分佈式計算和存儲能力。
- Meta Service:一組數據或一個文件,可以被切片並分佈在不同的Egg上,Meta service負責管理和定位文件的切片信息。
- Federation:由於聯邦學習的特殊性質,在訓練中,各個參與方之間往往會進行若干次數據互換。該服務爲訓練任務提供發送和接受數據的功能。
- Proxy:該服務是一個反向代理,是FATE集羣對外(訓練其他參與方)的唯一入口。
- FATE Board:向用戶提供訓練任務的可視化。
- FATE Serving:在線推理服務,用戶可以把訓練好模型推送到該服務後作在線推理。
KubeFATE簡介
由於FATE集羣包含了衆多服務,並且每一個服務的啓動都需要不同的配置和依賴,以至於使用存在一定門檻。此外由於多個服務之間有相互依賴,一個服務的失敗可能導致整個集羣的不可用,這給系統的運維也帶來了一定的挑戰。基於這個出發點,VMware和微衆聯合開發了KubeFATE項目,致力於解決聯邦學習的使用門檻和降低運維的成本。目前,KubeFATE和FATE最新的版本爲1.3.0,本文後續所有與它們相關的操作都將基於此版本。
由於KubeFATE使用了容器技術對FATE進行了封裝,因此相對於傳統的安裝部署,使用KubeFATE有以下優點:
- 使用簡單,免除缺失依賴軟件包的煩惱。
- 配置方便,一個配置文件就能部署多套集羣。
- 管理靈活,可按需增減集羣規模。
- 適用於雲環境。
目前KubeFATE支持使用Docker-Compose和Kubernetes兩種方式來部署和管理FATE集羣,分別面向了測試開發和生產這兩種使用場景。本文主要關注於測試開發的部署,因此在接下來的部署中會使用Docker-Compose這種方式。Kubernetes的方式將另文敘述。
KubeFATE的工作流程主要分成兩部分,分別是
根據用戶定義的配置文件生成FATE集羣的啓動文件。
拷貝啓動文件到指定機器上,並使用docker-compose命令啓動容器。
通常,負責生成啓動文件的服務器稱爲部署機,而負責運行容器的服務器稱爲目標機,部署機和目標機是在邏輯上的劃分。在本文中,部署機和目標機爲同一臺機器。
使用KubeFATE和Docker-Compose來部署單節點聯邦學習平臺
由於KubeFATE使用了容器作爲其底層工具,因此在開始使用KubeFATE之前,這裏也簡單介紹下容器、Docker等相關的概念。
容器也稱Linux Container(簡稱LXC),它是與系統其他部分隔離開的一系列進程,主要由Namespace和Cgroup兩大機制來保證實現。其優點是:
- 高資源利用與隔離
- 輕量級
- 跨Linux發行
Docker屬於 LXC的一種封裝,提供簡單易用的容器使用接口。它可以將應用程序與依賴,打包在一個文件裏面,而當程序要運行的時候,Docker就爲這個程進行一些配置,使得該進程與系統中的其他進程隔離。總體來說,Docker向用戶提供了一套簡單易用的接口,以至於用戶可以很方便使用容器。而Docker-Compose 是對Docker 容器進行編排的工具,通過它用戶可以很方便的配置和管理多個容器。至於更多關於Docker的詳細資料,請大家參考Docker 官網:https://www.docker.com
文章接下來的部分將跟大家分享單節點的聯邦學習平臺如何部署。
目標
部署一套FATE集羣,集羣內擁有“FATE整體架構”中描述的所有部件。具體部署架構如下所示:
準備工作
一臺機器,虛擬機或者物理機,推薦2CPU,8GB內存,Linux操作系統並且能聯網,並以root用戶登錄。下文中部署機器和目標機器爲同一臺,IP地址爲192.168.1.1 。
在目標機上安裝Docker
# curl -fsSL https://get.docker.com -o get-docker.sh
# sh get-docker.sh
# usermod -aG docker $(whoami)
# exec $SHELL
驗證安裝
# docker version
Client: Docker Engine - Community
Version: 19.03.7
API version: 1.40
Go version: go1.12.17
Git commit: 7141c199a2
Built: Wed Mar 4 01:22:36 2020
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.7
API version: 1.40 (minimum version 1.12)
Go version: go1.12.17
Git commit: 7141c199a2
Built: Wed Mar 4 01:21:08 2020
在目標機上安裝Docker-Compose
# curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-#(uname -s)-#(uname -m)" -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
驗證安裝
# docker-compose version
docker-compose version 1.25.4, build unknown
docker-py version: 4.2.0
CPython version: 2.7.17
OpenSSL version: OpenSSL 1.1.1 11 Sep 2018
在目標機上下載Docker 鏡像(可選)
對於國內用戶來說從Dockerhub上下載鏡像可能會比較慢,可用以下方式代替:
# wget https://webank-ai-1251170195.cos.ap-guangzhou.myqcloud.com/fate_1.3.0-images.tar.gz
# docker load -i fate_1.3.0-images.tar.gz
驗證下載鏡像
# docker images
REPOSITORY TAG
federatedai/egg 1.3.0-release
federatedai/fateboard 1.3.0-release
federatedai/meta-service 1.3.0-release
federatedai/python 1.3.0-release
federatedai/roll 1.3.0-release
federatedai/proxy 1.3.0-release
federatedai/federation 1.3.0-release
federatedai/serving-server 1.2.2-release
federatedai/serving-proxy 1.2.2-release
redis 5
mysql 8
在部署機上下載並解壓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)
partyiplist=(192.168.1.1) #此處替換爲目標機的IP
servingiplist=(192.168.1.1) #此處替換爲目標機的IP
exchangeip=
在部署機上執行生成集羣啓動文件腳本
# bash generate_config.sh # 生成部署文件
在部署機上執行啓動集羣腳本
# bash docker_deploy.sh all
命令輸入後需要用戶輸入兩次目標機的root用戶的密碼
在目標機上驗證集羣狀態
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f8ae11a882ba fatetest/fateboard:1.3.0-release "/bin/sh -c 'cd /dat…" 5 days ago Up 5 days 0.0.0.0:8080->8080/tcp confs-10000_fateboard_1
d72995355962 fatetest/python:1.3.0-release "/bin/bash -c 'sourc…" 5 days ago Up 5 days 9360/tcp, 9380/tcp confs-10000_python_1
dffc70fc68ac fatetest/egg:1.3.0-release "/bin/sh -c 'cd /dat…" 7 days ago Up 7 days 7778/tcp, 7888/tcp, 50001-50004/tcp confs-10000_egg_1
dc23d75692b0 fatetest/roll:1.3.0-release "/bin/sh -c 'cd roll…" 7 days ago Up 7 days 8011/tcp confs-10000_roll_1
7e52b1b06d1a fatetest/meta-service:1.3.0-release "/bin/sh -c 'java -c…" 7 days ago Up 7 days 8590/tcp confs-10000_meta-service_1
50a6323f5cb8 fatetest/proxy:1.3.0-release "/bin/sh -c 'cd /dat…" 7 days ago Up 7 days 0.0.0.0:9370->9370/tcp confs-10000_proxy_1
4526f8e57004 redis:5 "docker-entrypoint.s…" 7 days ago Up 7 days 6379/tcp confs-10000_redis_1
586f3f2fe191 fatetest/federation:1.3.0-release "/bin/sh -c 'cd /dat…" 7 days ago Up 7 days 9394/tcp confs-10000_federation_1
ec434dcbbff1 mysql:8 "docker-entrypoint.s…" 7 days ago Up 7 days 3306/tcp, 33060/tcp confs-10000_mysql_1
68b1d6c68b6c federatedai/serving-proxy:1.2.2-release "/bin/sh -c 'java -D…" 32 hours ago Up 32 hours 0.0.0.0:8059->8059/tcp, 0.0.0.0:8869->8869/tcp, 8879/tcp serving-10000_serving-proxy_1
7937ecf2974e redis:5 "docker-entrypoint.s…" 32 hours ago Up 32 hours 6379/tcp serving-10000_redis_1
00a8d98021a6 federatedai/serving-server:1.2.2-release "/bin/sh -c 'java -c…" 32 hours ago Up 32 hours 0.0.0.0:8000->8000/tcp serving-10000_serving-server_1
在目標機上驗證集羣是否正確安裝
# docker exec -it confs-10000_python_1 bash
# cd /data/projects/fate/python/examples/toy_example
# python run_toy_example.py 10000 10000 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"
通過上述步驟,一個FATE的實例(單方)部署完成,後續文章將介紹如何部署多方互聯進行聯邦學習的訓練。
常見問題
如果前文的“toy_example”嘗試數次後仍沒有跑過,可以考慮是否因CPU版本太舊以至於指令集不支持的問題。具體操作如下:
進入egg容器
# docker exec -it confs-xxxx_egg_1 bash
查看storage-service日誌
# cat storage-service-cxx/logs/error.log
如果日誌出現“Illegal instruction (core dumped)”則考慮使用CPU更新點的服務器重新部署。如果該日誌沒有輸出則可以通過docker log的方式逐個查看服務日誌以定位具體問題。
作者介紹:
彭路,VMware 雲原生實驗室工程師,FATE/KubeFATE 項目貢獻者。