| 导语 AutoML是一种能将机器学习模型中特征工程、模型选择、超参选择等问题自动化解决的一种方案,使得机器学习模型无需人工干预即可被应用。而katib是一个基于kubernetes生态、简单且可扩展性强的AutoML的一种开源实现。腾讯内部的太极机器学习平台借鉴了katib的一些设计思想,使得AutoML能力集成到训练平台中。 本文将剖析katib框架,对其基本概念、框架和流程进行简要介绍。
一 、AutoML和katib介绍
AutoML
我们知道,机器学习的本质其实是针对某一种学习模型,搜索一组最优参数,使得预设的loss function最少。在这些模型参数之上,还有一组所谓超参数的东西,例如神经网络的层数、学习率、优化算法等,与普通参数不同的是,这些超参数都是在跑某组实验时事先固定好的,并不会在训练过程中调整。
为了避免每次训练都需要人工干预来调整超参数的情况,AutoML应运而生,AutoML将这些与特征、模型、优化、评价有关的重要步骤进行自动化地学习,使得机器学习模型无需人工干预即可被应用。
katib
对于现代机器学习,特别是深度学习而言,使用一组合适的算法训练一组实验需要大量的资源—无论是算力(cpu+gpu)还是存储。kubernetes作为当前资源容器化管理平台的王者,已成为业界机器学习平台的首选。
katib就是基于kubernetes生态的AutoML的一种开源实现,katib隶属于kubeflow社区,实现了一套云原生的超参数搜索与模型结构搜索系统,复用 Kubernetes 对 GPU 等资源的管理能力,同时保证系统的可扩展性。
二 、katib框架剖析
1. 三种crd
katib中有3种概念,分别是experiment、suggestion、trial,分别对应了三种crd,这三种crd相互配合,完成了AutoML对超参数的搜索。 experiment是AutoML的主体对象,用户首先需要构建一个experiment,experiment controller会根据experiment对象创建相应的suggestion对象,即搜索算法,之后根据suggestion对象的输出(即一组超参数),创建一系列的trial对象,即正在的训练实验。三种关系如下:
首先介绍这三种crd:
experiment
experiment表示一个AutoML的实验,当一个experiment完成之后,我们应该能得到这个AutoML搜索出来的最优超参数。一个典型的experiment的yaml如下:
apiVersion: "kubeflow.org/v1alpha2"
kind: Experiment metadata: namespace: kubeflow name: bayesianoptimization-experiment spec: parallelTrialCount: 3 maxTrialCount: 12 maxFailedTrialCount: 3 objective: type: maximize goal: 0.99 objectiveMetricName: Validation-accuracy additionalMetricNames: - accuracy algorithm: algorithmName: bayesianoptimization trialTemplate: goTemplate: rawTemplate: |- apiVersion: batch/v1 kind: Job metadata: name: {{.Trial}} namespace: {{.NameSpace}} spec: template: spec: containers: - name: {{.Trial}} image: katib/mxnet-mnist-example command: - "python" - "/mxnet/example/image-classification/train_mnist.py" - "--batch-size=64" {{- with .HyperParameters}} {{- range .}} - "{{.Name}}={{.Value}}" {{- end}} {{- end}} restartPolicy: Never parameters: - name: --lr parameterType: double feasibleSpace: min: "0.01" max: "0.03" - name: --num-layers parameterType: int feasibleSpace: min: "2" max: "5" - name: --optimizer parameterType: categorical feasibleSpace: list: - sgd - adam - ftrl
该yaml表示了一个experiment需要搜索3种超参数,分别是
采用的搜索算法是bayesianoptimization,搜索目标是Validation-accuracy,并且在Validation-accuracy大于0.99时停止搜索。
同时该experiment设定了最多跑12组实验,一次并行最多跑3组,如果超过3组实验失败了则停止。
suggestion
suggestion表示的是AutoML中的搜索算法,katib并没有实现某种特定的算法,而是给出了算法需要遵循的规范。搜索算法真正的实现是通过跑一个容器,并且该容器需要尊徐katib的一些通信规范实现的。一个典型的suggestion yaml如下:
apiVersion: kubeflow.org/v1beta1
kind: Suggestion
metadata:
labels:
controller-tools.k8s.io: "1.0"
name: bayesianoptimization-example
namespace: kubeflow
ownerReferences:
- apiVersion: kubeflow.org/v1beta1
blockOwnerDeletion: true
controller: true
kind: Experiment
name: bayesianoptimization-example
uid: c14270f4-d81f-4991-a049-00f0beb32770
spec:
algorithmName: bayesianoptimization
requests: 12
resumePolicy: LongRunning
status:
suggestionCount: 12
suggestions:
- name: bayesianoptimization-example-9xms9qr9
parameterAssignments:
- name: lr
value: "0.013988097299564232"
- name: num-layers
value: "4"
- name: optimizer
value: ftrl
- name: bayesianoptimization-example-9pk89ks2
parameterAssignments:
- name: lr
value: "0.01858578989212678"
- name: num-layers
value: "4"
- name: optimizer
value: ftrl
- name: bayesianoptimization-example-z7vftq6w
parameterAssignments:
- name: lr
value: "0.013979382191901278"
- name: num-layers
value: "5"
- name: optimizer
value: adam
这个yaml表示使用bayesianoptimization这个算法,从configmap中可以看出bayesianoptimization实际是一个docker镜像:
$ kubectl get configmaps -n kubeflow katib-config -o yaml
apiVersion: v1
data:
...
suggestion: |-
{
"hyperband": {
"image": "gcr.io/kubeflow-images-public/katib/v1beta1/suggestion-hyperband"
},
"bayesianoptimization": {
"image": "gcr.io/kubeflow-images-public/katib/v1beta1/suggestion-skopt"
}
}
...
当bayesianoptimization这个算法跑起来之后,suggestion controller会创建suggestion-skopt这个容器,会随着容器的运行产生新的超参数,并且写到status中,例如第一轮产生的超参数是--lr=0.013988097299564232,--num-layers=4,--optimizer=ftrl。这些超参数将会传递给trial跑一轮实验。
trial
trial表示的是在AutoML中的搜索算法给出一组超参后,真正使用这组超参跑一个真实的ML实验。一个典型的trial yaml中如下:
apiVersion: kubeflow.org/v1beta1
kind: Trial
metadata:
creationTimestamp: "2020-09-25T12:46:49Z"
finalizers:
- clean-metrics-in-db
generation: 1
labels:
controller-tools.k8s.io: "1.0"
experiment: bayesianoptimization-example
name: bayesianoptimization-example-4w96gvjb
namespace: kubeflow
ownerReferences:
- apiVersion: kubeflow.org/v1beta1
blockOwnerDeletion: true
controller: true
kind: Experiment
name: bayesianoptimization-example
uid: c14270f4-d81f-4991-a049-00f0beb32770
resourceVersion: "1242374"
uid: c1e395c9-27ea-4b3b-9e3b-933fb0130336
spec:
metricsCollector:
collector:
kind: StdOut
objective:
additionalMetricNames:
- Train-accuracy
goal: 0.99
metricStrategies:
- name: Validation-accuracy
value: max
- name: Train-accuracy
value: max
objectiveMetricName: Validation-accuracy
type: maximize
parameterAssignments:
- name: lr
value: "0.018575758156150434"
- name: num-layers
value: "2"
- name: optimizer
value: adam
runSpec:
apiVersion: batch/v1
kind: Job
metadata:
name: random-example-4w96gvjb
namespace: kubeflow
spec:
template:
spec:
containers:
- command:
- python3
- /opt/mxnet-mnist/mnist.py
- --batch-size=64
- --lr=0.018575758156150434
- --num-layers=2
- --optimizer=adam
image: docker.io/kubeflowkatib/mxnet-mnist
name: training-container
restartPolicy: Never
status:
completionTime: "2020-09-25T12:38:19Z"
observation:
metrics:
- latest: "0.939988"
max: "0.948447"
min: "0.927249"
name: Validation-accuracy
- latest: "0.947745"
max: "0.947745"
min: "0.910914"
name: Train-accuracy
startTime: "2020-09-25T12:37:18Z"
这个trial使用bayesianoptimization算法产生的超参数--lr=0.018575758156150434,--num-layers=2,--optimizer=adam来跑mxnet-mnist实验。实验结果是Train-accuracy=0.948447,Validation-accuracy=0.948447。experiment将拿这组实验结果来选取最优的超参数。
2. 主要组件
katib主要由以下几个组件组成:
3. 框架图
katib的几个组件之间的关系如下所示:
4. 流程
下面简单介绍一下,一个用户从创建katib AutoML任务到获得结果之间,katib都做了哪些步骤,以mpijob为例:
1) 创建任务(experiment)
云原生用户提交experiment yaml给apiserver。apiserver创建experiment object。
2) 创建算法(suggestion)
3)创建训练实例(trial)
4)训练实例的状态更新
5) 实验结束
三、如何开发自己的搜索算法
1.如果用户想要新开发一些automl调参算法,需要创建一个grpc服务,并监听指定端口(由环境变量KATIB_SUGGESTION_PORT指定)
2. grpc的请求格式为:
type GetSuggestionsRequest struct {
Experiment *Experiment `protobuf:"bytes,1,opt,name=experiment"
json:"experiment,omitempty"`
Trials []*Trial `protobuf:"bytes,2,rep,name=trials"
json:"trials,omitempty"`
RequestNumber int32
`protobuf:"varint,3,opt,name=request_number,json=requestNumber"
json:"request_number,omitempty"`
}
3. grpc的回复格式为:
type GetSuggestionsReply struct {
ParameterAssignments []*GetSuggestionsReply_ParameterAssignments
`protobuf:"bytes,1,rep,name=parameter_assignments,json=parameterAssignments"
json:"parameter_assignments,omitempty"`
Algorithm *AlgorithmSpec
`protobuf:"bytes,2,opt,name=algorithm" json:"algorithm,omitempty"`
}
四、总结
katib是基于kubernetes生态,在kubeflow社区下的一种AutoML开源框架。它有3个概念,分别是experiment,suggestion和trial。experiment创建suggestion,suggestion根据当前trial给出新的超参数,并且由experiment使用超参数创建新的trial,最终从众多trial中选择结果最好的一组trial,使用该组trial的超参数作为最终的超参。