工作过程中,需要用到FATE联邦学习框架的隐私计算功能,但是公司内部仅仅也只是试用过。网上的资料也比较少,官方文档也语焉不详,于是只能摸着石头过河,结合官方文档和百度参考学习。
一、FATE概念
1. 角色
在Fate的概念中分成3种角色,Guest、Host、Arbiter
- Guest表示数据应用方,在纵向算法中,Guest往往是有标签y的一方。一般是由Guest发起建模流程。
- Host是数据提供方
- arbiter是用来辅助多方完成联合建模的,主要的作用是用来聚合梯度或者模型,比如纵向lr里面,各方将自己一半的梯度发送给arbiter,然后arbiter再联合优化等等,arbiter还参与以及分发公私钥,进行加解密服务等等。
2.术语
party
: 站点,一般物理上指一个FATE单机或者FATE集群
job
: 作业
task
: 任务, 一个作业由多个任务构成
component
: 组件,静态名称,提交作业时需要两个描述配置文件,分别描述该作业需要执行的组件列表、组件依赖关系、组件运行参数
dsl
: 指用来描述作业中组件关系的语言, 可以描述组件列表以及组件依赖关系
component_name
: 提交作业时组件的名称,一个作业可以有多个同样的组件的,但是 component_name
是不一样的,相当于组件的实例, 一个component_name
对应的组件会生成一个task
运行
componet_module_name
: 组件的类名
model_alias
: 跟 component_name
类似,就是用户在 dsl 里面是可以配置输出的 model 名称的
DTable
:Fate中的表概念
EGGROLL
: 分布式计算存储引擎
二、数据上传
- Upload(数据上传)
- 外部存储直接导入到FATE Storage,创建一个新的DTable
- 作业运行时,Reader直接从Storage读取
- Table Bind(数据表绑定)
- 外部存储地址绑定到到FATE一个新的DTable
- 作业运行时,Reader通过Meta从外部存储读取数据并转存到FATE Storage
- 打通大数据生态:HDFS,Hive/MySQL

2.1.Upload
用于上传建模任务的输入数据到fate所支持的存储系统。存储系统默认为EGGROLL ,同时还支持HDFS 、LOCALFS
执行方式支持命令行或api的形式,命令行执行语句如下:
sh
flow data upload -c ${conf_path}
注: 其中conf_path为参数配置Json文件的路径,具体参数如下
选项
参数名 | 必选 | 类型 | 说明 |
---|---|---|---|
file | 是 | string | 数据存储路径 |
id_delimiter | 是 | string | 数据分隔符,如"," |
head | 否 | int | 数据是否有表头 |
partition | 是 | int | 数据分区数 |
storage_engine | 否 | string | 存储引擎类型,默认"EGGROLL",还支持"HDFS","LOCALFS", "HIVE"等 |
namespace | 是 | string | 表命名空间 |
table_name | 是 | string | 数据表名称 |
storage_address | 否 | object | 需要填写对应存储引擎的存储地址 |
use_local_data | 否 | int | 默认1,代表使用client机器的数据;0代表使用fate flow服务所在机器的数据 |
drop | 否 | int | 是否覆盖上传 |
extend_sid | 否 | bool | 是否新增一列uuid id,默认False |
auto_increasing_sid | 否 | bool | 新增的id列是否自增(extend_sid为True才会生效), 默认False |
with_meta | 否 | bool | 是否携带meta数据, 默认False |
meta | 否 | object | 元数据, 默认为空,with_meta为true生效 |
meta信息
参数名 | 必选 | 类型 | 说明 |
---|---|---|---|
input_format | 否 | string | 数据格式(danse、svmlight、tag:value),用来判断 |
delimiter | 否 | string | 数据分隔符,默认"," |
tag_with_value | 否 | bool | 对tag的数据格式生效,是否携带value |
tag_value_delimiter | 否 | string | tag:value数据分隔符,默认":" |
with_match_id | 否 | bool | 是否携带match id |
id_list | 否 | object | id列名称,开启extend_sid下生效,如:["imei", "phone"] |
id_range | 否 | object | 对于tag/svmlight格式数据,哪几列为id |
exclusive_data_type | 否 | string | 特殊类型数据列格式 |
data_type | 否 | string | 列数据类型,默认"float64 |
with_label | 否 | bool | 是否有标签,默认False |
label_name | 否 | string | 标签名,默认"y" |
label_type | 否 | string | 标签类型, 默认"int" |
以上传csv文件为例:
json
{
"file": "/data/projects/fate/examples/test_case_fl/test_case/data/breast_hetero_host.csv",
"table_name": "test_case_host",
"namespace": "test_case",
"head": 1,
"partition": 8
}
2.2.table bind
除了直接上传的方式,还可通过table bind将真实存储地址映射到fate存储表。我理解就是不用提前上传,需要执行具体任务命令时才会触发上传任务,然后转换为Fate平台的DTable形式。
sh
flow table bind -c ${conf_path}
注: 其中conf_path为参数配置Json文件的路径,具体参数如下
选项
参数名 | 必选 | 类型 | 说明 |
---|---|---|---|
name | 是 | string | fate表名 |
namespace | 是 | string | fate表命名空间 |
engine | 是 | string | 存储引擎, 支持"HDFS", "MYSQL", "PATH" |
adress | 是 | object | 真实存储地址 |
drop | 否 | int | 覆盖以前的信息 |
head | 否 | int | 是否有数据表头 |
id_delimiter | 否 | string | 数据分隔符 |
id_column | 否 | string | id字段 |
feature_column | 否 | array | 特征字段 |
以mysql数据源为例
json
{
"engine": "MYSQL",
"address": {
"user": "fate",
"passwd": "fate",
"host": "127.0.0.1",
"port": 3306,
"db": "experiment",
"name": "breast_hetero_guest"
},
"namespace": "experiment",
"name": "breast_hetero_guest",
"head": 1,
"id_delimiter": ",",
"partitions": 10,
"id_column": "id",
"feature_column": "y,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9"
}
2.3. 数输入组件:Reader
简要描述:
- reader组件为fate的数据输入组件;
- reader组件可将输入数据转化为指定存储类型数据;
参数配置:
submit job时的conf中配置reader的输入表的命名空间和表名:
json
{
"role": {
"guest": {
"0": {
"reader_0": {
"table": {
"name": "test_case_host",
"namespace": "test_case"
}
}
}
}
}
}
三、上传任务
css
flow job submit [options]
options配置
参数名 | 必选 | 类型 | 说明 |
---|---|---|---|
-d, --dsl-path | 是 | string | job dsl的路径 |
-c, --conf-path | 是 | string | job conf的路径 |
如果要构建一个联邦学习作业,并提交到调度系统执行,需要两个Json配置文件:job dsl 和job conf
- job dsl配置运行的组件:列表、输入输出关系
- job conf配置组件执行参数、系统运行参数
3.1. Job DSL配置说明
DSL 的配置文件同样采用 json 格式。
3.1.1 配置规范
在这个配置文件的格式为:第一级是 components
,用来表示这个任务将会使用到的各个模块。
json
{
"components" : {
...
}
}
每个独立的模块定义在 "components" 之下,示例如下:
json
{
"components": {
"reader_0": {
"module": "Reader",
"output": {
"data": [
"data"
]
}
},
"data_transform_0": {
"module": "DataTransform",
"input": {
"data": {
"data": [
"reader_0.data"
]
}
},
"output": {
"data": [
"data"
],
"model": [
"model"
]
}
}
//........
}
3.1.2 数据接入规范
所有数据需要通过Reader 模块从数据存储拿取数据,注意此模块仅有输出output
json
"reader_0": {
"module": "Reader",
"output": {
"data": [
"data"
]
}
}
3.1.3 模块参数说明
1.2中的reader也可视为一个模块
module_name:模块的键。用户需要使用模块名加数字 _num 作为对应模块的 key,例如 dataio_0,并且数字应从 0 开始计数。这用于区分可能存在的多个相同种类的模块。
-
module :用来指定使用的模块。这个参数的内容需要和federatedml/conf/setting_conf 下各个模块的文件名保持一致。模块参考列表:联邦机器学习模块
-
input:输入。分为两种输入类型,分别是 data 和 model。
-
output:输出。和 input 一样,有 data 和 model 两种类型。
可以在以上模块参考表中概览各个模块的介绍,也能在子目录中获取详细的参数配置说明
1.3.1 module
module 用来指定使用的组件模块,所有可选module名称参考:联邦机器学习模块
json
"hetero_feature_binning_1": {
"module": "HeteroFeatureBinning",
...
}
3.1.3.2 input
上游输入,分为两种输入类型,分别是数据和模型。
3.1.3.2.1 数据输出
上游数据输入,分为三种输入类型:
- data: 一般被用于 data-transform模块, feature_engineering 模块或者evaluation 模块
- train_data: 一般被用于 homo_lr, hetero_lr 和 secure_boost模块。如果出现了 train_data 字段,那么这个任务将会被识别为一个 fit 任务
- validate_data: 如果存在 train_data字段,那么该字段是可选的。如果选择保留该字段,则指向的数据将会作为validation set
- test_data: 用作预测数据,如提供,需同时提供model输入。
一般最常用的还是data
3.1.3.2.2 模型输出
上游模型输入,分为两种输入类型:
- model : 用于同种类型模块的模型输入。例如,hetero_binning_0 会对模型进行 fit,然后 hetero_binning_1 将会使用 hetero_binning_0 的模型输出用于 predict 或 transform。
代码示例:
json
"hetero_feature_binning_1": {
"module": "HeteroFeatureBinning",
"input": {
"data": {
"data": [
"data_transform_1.validate_data"
]
},
"model": [
"hetero_feature_binning_0.fit_model"
]
},
"output": {
"data": ["validate_data"],
"model": ["eval_model"]
}
}
- isometric_model : 用于指定继承任意上游模块的模型输入。 例如,feature selection 的上游组件是 feature binning,它将会用到 feature binning 的信息来作为 feature importance。
代码示例:
json
"hetero_feature_selection_0": {
"module": "HeteroFeatureSelection",
"input": {
"data": {
"data": [
"hetero_feature_binning_0.train"
]
},
"isometric_model": [
"hetero_feature_binning_0.output_model"
]
},
"output": {
"data": ["train"],
"model": ["output_model"]
}
}
3.1.3.3 output
输出与输入一样,分为数据和模型输出
3.1.3.3.1 数据输出
数据输出,分为四种输出类型:
- data: 常规模块数据输出
- train_data: 仅用于Data Split
- validate_data: 仅用于Data Split
- test_data: 仅用于Data Split
3.1.3.3.2 模型输出
模型输出,无特殊说明。
3.2. Job Conf配置说明
- initiator:指定启动器的角色和参与方ID。
- role:指示所有角色的所有参与方ID。每个角色的 party_id 以列表形式存在,因为一个任务可能涉及到多个 party 担任同一种角色。
- job_parameters:配置作业运行时的主要系统参数
- component_parameters:组件运行参数
json
{
"dsl_version": 2,
"initiator": {
"role": "guest",
"party_id": 9999
},
"role": {
"arbiter": [
9999
],
"host": [
10000
],
"guest": [
9999
]
},
"component_parameters": {
"common": {
"hetero_kmeans_0": {
"k": 3,
"max_iter": 10
},
"evaluation_0": {
"eval_type": "clustering"
}
},
"role": {
"host": {
"0": {
"data_transform_0": {
"with_label": false
},
"reader_0": {
"table": {
"name": "test_case_307_host",
"namespace": "test_case"
}
}
}
},
"guest": {
"0": {
"data_transform_0": {
"with_label": true,
"output_format": "dense"
},
"reader_0": {
"table": {
"name": "test_case_307_guest",
"namespace": "test_case"
}
}
}
}
}
}
}
Job Conf用于设置各个参与方的信息, 作业的参数及各个组件的参数。
内容包括如下:
3.2.1 DSL版本
描述 配置版本,默认不配置为1,建议配置为2 样例
json
"dsl_version": "2"
3.2.2 作业参与方
3.2.2.1 发起方 initiator
描述 任务发起方的role和party_id。 样例
json
"initiator": {
"role": "guest",
"party_id": 9999
}
3.2.2.2 所有参与方 role
描述 各参与方的信息。 说明 在 role 字段中,每一个元素代表一种角色以及承担这个角色的 party_id。每个角色的 party_id 以列表形式存在,因为一个任务可能涉及到多个 party 担任同一种角色。 样例
json
"role": {
"guest": [9999],
"host": [10000],
"arbiter": [10000]
}
3.2.3 组件运行参数
还有一个系统运行参数,不过一般使用默认配置即可,这里略过。
3.2.3.1 参数应用范围策略设置
- 应用于所有参与方,使用common范围标识符
json
"commom": {
}
- 仅应用于某参与方,使用role范围标识符,使用(role:)party_index定位被指定的参与方,直接指定的参数优先级高于common参数
json
"role": {
"guest": {
"0": {
}
}
}
其中common配置下的参数应用于所有参与方。如果需要特殊指定role-guest-0配置下的参数表示应用于guest角色0号下标的参与方,优先级高于common
3.2.3.2 参考配置
hetero_kmeans_0
与evaluation_0
两个组件的运行参数,放在common范围下,应用于所有参与方- 对于
reader_0
与data_transform_0
两个组件的运行参数,依据不同的参与方进行特定配置,这是因为通常不同参与方的输入参数并不一致,所有通常这两个组件一般按参与方设置
json
"component_parameters": {
"common": {
"hetero_kmeans_0": {
"k": 3,
"max_iter": 10
},
"evaluation_0": {
"eval_type": "clustering"
}
},
"role": {
"host": {
"0": {
"data_transform_0": {
"with_label": false
},
"reader_0": {
"table": {
"name": "test_case_307_host",
"namespace": "test_case"
}
}
}
},
"guest": {
"0": {
"data_transform_0": {
"with_label": true,
"output_format": "dense"
},
"reader_0": {
"table": {
"name": "test_case_307_guest",
"namespace": "test_case"
}
}
}
}
}
}
3.2.4. 多Host 配置
多Host任务应在role下列举所有host信息
示例如下:
json
"role": {
"guest": [
10000
],
"host": [
10000, 10001, 10002
],
"arbiter": [
10000
]
}
各host不同的配置应在各自对应模块下通过下角标分别配置参数
示例如下:
json
"component_parameters": {
"role": {
"host": {
"0": {
"reader_0": {
"table":
{
"name": "hetero_breast_host_0",
"namespace": "hetero_breast_host"
}
}
},
"1": {
"reader_0": {
"table":
{
"name": "hetero_breast_host_1",
"namespace": "hetero_breast_host"
}
}
},
"2": {
"reader_0": {
"table":
{
"name": "hetero_breast_host_2",
"namespace": "hetero_breast_host"
}
}
}
}
}
}
四、任务流程
因为Fate平台的任务设置不是很符合我们对任务流程从开始到结束的流程,所以在这里以易于理解的形式梳理一下。
1. 数据接入平台
参考二的数据上传
- 通过Upload上传数据到Fate平台
- 或通过table bind命令将数据源绑定到Fate平台,待使用时传入
2. 指定任务接入数据
参考3.2.3.2 ,在job conf 配置文件中 配置component_parameters role项中的reader设置接入数据源
3. 配置任务参数
参考3.2.1 和3.2.2 ,在job conf配置文件中配置DSL版本与任务参与方
4. 设置任务模块
参考3.1.3设计需要的模块以及模块执行流程
5. 上传任务,保存jobId
在提交任务后,会得到一个返回结果,其中有jobId。
不要看那个data,那不是结果数据。下面data.参数项已经给出了。
参数名 | 类型 | 说明 |
---|---|---|
retcode | int | 返回码 |
retmsg | string | 返回信息 |
jobId | string | 作业ID |
data | dict | 返回数据 |
data.dsl_path | string | 依据提交的dsl内容,由系统生成的实际运行dsl配置的存放路径 |
data.runtime_conf_on_party_path | string | 依据提交的conf内容,由系统生成的在每个party实际运行conf配置的存放路径 |
data.board_url | string | fateboard查看地址 |
data.model_info | dict | 模型标识信息 |
6.下载输出数据
通过以上jobId,以及指定参与方id,参与角色,组件名可将数据输出
css
flow tracking output-data [options]
选项
参数名 | 必选 | 类型 | 说明 |
---|---|---|---|
-j, --job-id | 是 | string | 作业id |
-r, --role | 是 | string | 参与角色 |
-p, --partyid | 是 | string | 参与方id |
-cpn, --component-name | 是 | string | 组件名,与job dsl中的保持一致 |
-o, --output-path | 是 | string | 输出数据的存放路径 |
返回
参数名 | 类型 | 说明 |
---|---|---|
retcode | int | 返回码 |
retmsg | string | 返回信息 |
data | dict | 返回数据 |
jobId | string | 作业id |
有一点存疑,官网没有给出一个任务的输出,仅给出对应组件的输出,也就说我们必须知道所有的信息,才能拿到预测组件的输出数据。感觉这样可操作性确实比较强。