导语:近10年,机器学习在人工智能领域迅猛发展,其中一个关键的推动燃料就是人类社会积累的大量数据。然而,尽管数据规模在总体上快速增长,绝大部分数据却分散在各个公司或部门内,导致数据被严重隔离和碎片化;也正因为此,各个组织间有很强的数据合作意愿,可是基于数据隐私和安全的考量,要在合规的情况下实现数据合作面临着诸多挑战。
基于上述原因形成的数据孤岛正严重阻碍着各方协同数据共同构建人工智能模型,也因此迫切需要一种新的机制来解决上述问题。联邦学习应运而生,通过这一新兴技术,可以在确保用户隐私和数据安全的前提下,各组织间交换模型信息的过程被精心地设计和全程加密,使得没有组织能够猜测到其他任何组织的隐私数据内容,但却实现联合建模的目的。
PowerFL是腾讯TEG自研的联邦学习平台,已经在金融云、广告联合建模等业务场景中开始落地,并取得了初步效果。PowerFL以技术赋能的方式,为分布在不同部门和团队的数据搭建互通的桥梁,在保护数据隐私的前提下,使数据合力成为可能。本文将首先从平台框架、部署视图和网络拓扑结构等三个方面来介绍PowerFL的整体技术架构,并在此基础上介绍如何一键部署PowerFL以及如何定义联邦任务流来提交联邦任务。
- PowerFL的平台框架介绍
- PowerFL的部署视图及关键组件
- PowerFL的网络拓扑
- 快速部署PowerFL
- 准备k8s集群
- 准备Yarn集群(可选)
- 准备安装客户端
- 一键部署PowerFL
- 通过flow-server提交联邦任务
- 联邦任务编排和调度的流程
- 总结
PowerFL的平台框架介绍
从平台框架的角度,PowerFL从以下五个层次来构建整个联邦学习的技术和生态,从最底层依次往上:
- 计算和数据资源:PowerFL支持主流的两种计算资源调度引擎YARN和K8S:所有的服务组件均以容器的形式部署在K8S集群上,大大简化部署和运维成本,可以方便地实现服务的容错与扩缩容;同时,所有的计算组件均通过YARN集群进行调度,从而在保障大规模机器学习任务并行加速的同时,保证计算的稳定性与容错性。此外,PowerFL还支持从多种数据源拉取数据,包括TDW,Ceph,COS,HDFS等。
- 计算框架:在计算和数据资源之上,PowerFL实现了一套针对联邦学习算法的计算框架,与传统的机器学习框架相比,这套框架重点解决了联邦学习算法和应用在实践过程中最常见的几个难点:1)安全加密:PowerFL实现了各种常见的同态加密、对称和非对称加密算法(包括Paillier、RSA非对称加密等算法);2)分布式计算:基于Spark on Angel的高性能分布式机器学习框架,通过PowerFL可以轻松实现各种高效的分布式联邦学习算法;3)跨网络通信:PowerFL提供了一套多方跨网络传输接口,底层采用消息队列组件,在保证数据安全的前提下,实现了稳定可靠的高性能跨网传输;4)TEE/SGX支持:除了通过软件的方式来保障数据安全,PowerFL还支持通过TEE/SGX在Enclave中对数据进行加密和计算,从而以硬件的方式实现算法性能的大幅提升。
- 算法协议:基于上述计算框架,PowerFL针对不同场景实现了常见的联邦算法协议:1)在分析场景下,PowerFL支持联合查询和两方/多方的样本对齐;2)针对建模场景,PowerFL支持联邦特征工程(包括特征选择、特征过滤和特征转换等)、联邦训练(包括逻辑回归、GBDT,DNN等)以及联合预测。
- 产品交互:从终端用户的角度,PowerFL作为联邦学习的应用产品,既支持以REST API的形式调起联邦任务,也支持各模型参与方在联合工作区上协同工作,以拖拽算法组件的方式来构建和配置联邦任务流,并进行用户、资源、配置以及任务的管理。
- 应用场景:在完善了上述联邦学习的基础设施之后,PowerFL可以在安全合规的前提下解决金融风控、广告推荐、人群画像、联合查询等多个应用场景下由于数据隔离和碎片化造成的“数据孤岛”问题,真正赋能遵守隐私规范的人工智能和大数据应用。
PowerFL的部署视图及关键组件
从部署视图的角度来看,PowerFL包括了服务层和计算层:
- 服务层构建在K8S集群之上,利用了其优异的资源调度能力、完善的扩缩容机制以及稳定的容错性能,将PowerFL的常驻服务以容器的形式部署在服务节点之上。这些常驻服务组件包括了:
- 消息中间件:负责所有服务和计算组件之间的事件驱动、各方计算组件之间的算法同步及加密数据异步通信。
- 任务流引擎:负责控制单侧联邦任务流的调度,执行节点按事先定义的任务流顺序以容器的方式被调起,计算任务在执行节点中执行,或在执行节点中向YARN集群提交计算任务。
- 任务面板:负责收集任务流中各个算法组件每轮迭代或最终模型输出结果的关键性能指标展示、如AUC,Accuracy、K-S,特征重要性等。
- 多方联邦调度引擎:负责多方之间联邦任务的调度和同步,并提供了一套API提供了联邦任务流的创建、任务的发起、终止、暂停、删除、状态查询等接口。
- 计算层构建在YARN集群之上,充分利用了Spark大数据生态套件,负责PowerFL运行时各个算法组件的分布式计算。计算任务实际上由服务层的任务节点发起并向YARN集群申请资源运行PowerFL的联邦算子,基于Spark on Angel的计算框架,保证了算法的高度并行和优异性能。
PowerFL的网络拓扑
站在内网用户的角度,PowerFL通过k8s的ingress对内网用户暴露服务路径:
- 通过访问http://domain/可访问任务面板的界面,了解当前任务的运行状态、任务运行过程中的关键日志、关键性能指标展示等;
- 通过访问http://domain/pipelines可访问任务流引擎的界面,查看本侧任务的运行阶段:
- 通过访问http://domain/flow-server可访问flow-server的REST API。
计算任务(如spark任务的driver和executor)和服务层组件之间,则通过消息中间件来提供通信;
计算任务执行过程中得到的中间加密结果和需要同步的任务状态信息,则通过各自消息中间件实现跨外网同步。
快速部署PowerFL
在整体了解完PowerFL的平台框架、部署视图以及网络拓扑结构后,以下将介绍如何快速部署PowerFL,正如上述提到的,PowerFL分成服务层组件和计算层,分别构建在k8s集群和YARN集群之上。在部署PowerFL之前,需要先准备好这两种集群环境(如果计算任务不需要分布式环境,也可以不需要准备YARN集群环境)。
在进行以下操作之前,获取最新版本的安装包并解压。
准备k8s集群
机器配置要求:
- 机器数量:1 台
- 硬件配置:16G Mem、CPU 4 、硬盘100G
- OS及版本:建议CentOS 7.0
- Docker 1.8
如果是在测试环境的话,可参考文档安装Minikube,VM driver可选kvm2(linux)或者hyperkit,或者VirtualBox (macOS),通过Minikube创建k8s:
代码语言:javascript复制minikube start --memory=8192 --cpus=4
如果是在生产环境中安装k8s ,可以参考k8s的官方文档,在生产环境部署k8s集群,可选方案包括:
- 使用kubeadm来进行安装。
- 使用kops来进行安装.
- 使用KRIB来进行安装.
- 使用Kubespray来进行安装.
- 也可以使用腾讯云的TKE
如果需要离线安装k8s,可参考安装包目录下的offline-k8s-deploy里的文档进行安装。
准备Yarn集群(可选)
可以参考Apache Ambari的文档来安装YARN集群,安装完成后准备好hadoop的配置文件,放在hadoop-config目录下:
代码语言:javascript复制core-site.xml hdfs-site.xml mapred-site.xml yarn-site.xml
并往k8s集群中导入上述配置文件,这里导入的配置名为hadoop:
代码语言:javascript复制kubectl -n power-fl-[partyId] create configmap hadoop --from-file=./hadoop-config
准备安装客户端
- 安装jq和envsubst# 如果是Ubuntu sudo apt-get install jq envsubst # 如果是CentOS sudo yum install jq envsubst
- 安装helm 3.0 可参考Helm的官方文档进行安装,简单来说,可进行如下操作:
- macOS使用Homebrew进行安装:brew install helm
- Windows可使用Chocolatey进行安装choco install kubernetes-helm
- 通过命令行进行安装curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
一键部署PowerFL
以下操作均在客户端机器上进行操作,且执行目录为Fl-deploy的根目录下:
代码语言:javascript复制cd FL-deploy
首次安装
- 准备kubectl的配置文件: mkdir kube cp ~/.kube/config ./kube
- 复制环境配置模板文件,并设置相应的环境变量: cp _powerfl_env.sh ./powerfl_env.sh vim ./powerfl_env.sh #!/bin/bash # 设置参与方id,各参与方的id必须唯一 export PARTY_ID=10000 # 设置参与方访问powerfl相关服务的域名 export DOMAIN=powerfl-10000.com # 内网内访问MQ的地址,用于内部Hadoop集群访问 export INTERNAL_MQ_HOST=xx.xx.xx.xx # 内网内访问MQ的tcp端口 export INTERNAL_MQ_TCP_PORT="xxxx" # 暴露给外网的MQ-proxy的http端口(对于默认的k8s配置,端口范围为30000-32767) export EXPOSE_MQ_HTTP_PORT="xxxx" # 暴露给外网的MQ的tcp端口(对于默认的k8s配置,端口范围为30000-32767) export EXPOSE_MQ_TCP_PORT="xxxx" # 设定不需要安装的组件,用空格分开 export DISABLED_COMPONENTS="" # 其它参与方的id,用空格分开 export OTHER_PARTIES="20000" # 其它参与方的MQ配置,如OTHER_PARTIES="20000 30000" # 则需要分别配置 # PARTY_MQ_HTTP_URL_20000和PARTY_MQ_PROXY_URL_20000 # 和 PARTY_MQ_HTTP_URL_30000和PARTY_MQ_PROXY_URL_30000 export PARTY_MQ_HTTP_URL_20000=yy.yy.yy.yy:yyyy export PARTY_MQ_PROXY_URL_20000=yy.yy.yy.yy:yyyy
- 执行脚本安装: ./deploy.sh setup
同时安装多个参与方
如果需要在同一个k8s集群上安装多个参与方,则可拷贝多份 _powerfl_env.sh作为不同参与方的环境配置文件,并在执行部署脚本时指定(如果未指定,则默认使用当前目录下的powerfl_env.sh作为环境配置文件,如上所示):
代码语言:javascript复制cp _powerfl_env.sh ./powerfl-10000.sh
vim ./powerfl-10000.sh # 修改PARTY_ID等配置
cp _powerfl_env.sh ./powerfl-20000.sh
vim ./powerfl-20000.sh # 修改PARTY_ID等配置
# 部署参与方10000,指定配置文件powerfl-10000.sh
./deploy.sh setup ./powerfl-10000.sh
# 部署参与方20000, 指定配置文件powerfl-20000.sh
./deploy.sh setup ./powerfl-20000.sh
更新系统
如果需要修改系统相关的配置,则可修改对应环境配置文件和组件配置文件,并执行:
代码语言:javascript复制./deploy.sh upgrade
# 如果指定配置文件./deploy.sh upgrade ./powerfl-10000.sh
卸载系统
注意:执行此操作为删除powerfl的所有数据,不可恢复:
代码语言:javascript复制./deploy.sh cleanup
# 如果指定配置文件./deploy.sh cleanup ./powerfl-10000.sh
通过flow-server提交联邦任务
在安装完PowerFL之后,可通过指定的DSL编写任务流和任务参数配置文件向flow-server提交联邦任务,在介绍具体使用方法之前,首先了解一下PowerFL的联邦任务编排和调度流程。
联邦任务编排和调度的流程
1)编写任务流文件pipeline.yaml,向flow-server导入pipeline:
代码语言:javascript复制curl --request POST 'http://{domain}/flow-server/pipelines' --form 'file=@pipeline.yaml'
如果成功会返回pipeline的id;针对刚才导入的pipeline,编写任务配置参数文件job.yaml(稍后会介绍DSL),向flow-server提交任务:
代码语言:javascript复制curl -request POST 'http://{domain}/flow-server/pipelines/{pipeline_id}/jobs' --form 'parameters=@job_parameters.yaml'
2)flow-server在收到任务请求提交之后,会随机生成本次任务的id、注入全局的相关配置构建出最终供任务流引擎调度用的DSL并向其提交任务流。
3)任务流引擎根据上述DSL文件,按任务流定义的节点顺序依次向K8S集群申请资源,调起对应节点的运行时容器;
4和5)运行时容器启动后,会根据注入的环境变量信息,向YARN集群申请资源,启动driver和executor,调起具体的算法流程,执行并行计算任务,至此,本侧的算法任务启动完成。
6)另一边,flow-server在收到任务请求提交之后,会将该任务的配置文件信息传给本地的消息中间件;
7)本地消息中间件通过跨网同步,将上述任务配置文件同步给其它参与方的消息中间件;
8)其它参与方的flow-server监听消息中间件任务提交的topic,收到新的联邦任务的启动请求;
9)之后的过程同3)4)5)
任务配置参数文件的格式如下:
代码语言:javascript复制parties: [ "10000=guest", "20000=host" ]
common-args:
spark-master-name: local[*]
runtime-image: power_fl/runtime:develop
parties-args:
10000:
hadoop-config: hadoop
hadoop-user-name: root
hdfs-libs-path: hdfs:///fl-runtime-libs
spark-submit-args: ""
input: /opt/spark-app/fl-runtime/data/a9a.guest.head
output: /tmp/a9a.guest.output
20000:
hadoop-config: hadoop
hadoop-user-name: root
hdfs-libs-path: hdfs:///fl-runtime-libs
spark-submit-args: ""
input: /opt/spark-app/fl-runtime/data/a9a.host.head
output: /data/a9a.host.output
上述文件共由三个主要部分构成:
- parties:以数组的格式指定联邦任务的各个参与方,以partyId=role的格式指定各参与方的id及在本次任务中的角色
- common-args:指定所有参与方共同使用的参数,可配置的参数需与pipline.yaml中指定的spec.arguments.parameters的一致。
- parties-args:指定各个参与方各自的参数,包括hadoop配置信息、任务算法参数配置信息等。
总结
PowerFL从计算与数据资源、计算框架、算法协议、产品交互和应用场景五个层次从底向上夯实整个联邦学习的技术和生态,将整个系统以云原生的方式架构于k8s集群之上,并充分利用YARN集群的大数据生态,基于Spark on Angel来实现联邦任务的高性能分布式计算。本文首先介绍了PowerFL的整体架构,包括技术栈、关键组件和网络拓扑结构,并在此基础上介绍如何一键部署PowerFL以及如何定义联邦任务流来提交联邦任务。希望本文能帮助大家快速上手联邦学习,深入了解这一新的基于隐私保护的机器学习建模机制,并将其应用于电子商务、金融、医疗、教育、城市计算等更多的领域。
扫码关注 | 即刻了解腾讯大数据技术动态