Press "Enter" to skip to content

Automl框架katib浅析

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

| 导语    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种超参数,分别是

 

–lr 学习率,搜索范围从0.01-0.03;

 

–num-layers 网络层数,范围是2-5;

 

–optimizer 优化算法,候选者是sgd,adam,ftrl。

 

采用的搜索算法是 bayesianoptimization ,搜索目标是 Validation-accuracy ,并且在 Validation-accuracy 大于0.99时停止搜索。

 

同时该experiment设定了最多跑12组实验,一次并行最多跑3组,如果超过3组实验失败了则停止。

 

suggestion

 

suggestion表示的是AutoML中的搜索算法,katib并没有实现某种特定的算法,而是给出了算法需要遵循的规范。搜索算法真正的实现是通过跑一个容器,并且该容器需要尊徐katib的一些通信规范实现的。一个典型的suggestion yaml如下:

 

a piVersion : 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中如下:

 

a piVersion: 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主要由以下几个组件组成:

 

katib controllers :katib的主逻辑部分,分为以下三个controller:

 

experiment controller :根据experiment创建suggestion和trials,同时根据trials的状态,从suggestion中获取hyper parameters,创建新的trials。也就是说experiment是suggestion和trials的桥梁。

 

suggestion controller :AutoML的算法控制器,接受trials和experiment,输出hyper parameters。

 

trial controller :训练实验控制器,根据suggestion产生的hyper parameters,构建真正的训练程序,并实时更新训练状态。

 

db-manager : 一个gRPC server,用于接受用户存储db数据和获取db数据的请求。

 

pod webhook :拦截automl mpijob创建的pod,并且在pod中增加一个metrics sidecar container。这个metrics container会收集pod的训练日志,并上报给db-manager。

 

experiment webhook :主要用于校验用户的experiment。

 

3. 框架图

 

katib的几个组件之间的关系如下所示:

4. 流程

 

下面简单介绍一下,一个用户从创建katib AutoML任务到获得结果之间,katib都做了哪些步骤,以mpijob为例:

 

1) 创建任务(experiment)

 

云原生用户提交experiment yaml给apiserver。apiserver创建experiment object。

2) 创建算法(suggestion)

 

experiment controller观察到有新的experiment object产生,根据experiment创建一个suggestion object。

 

suggestion controller观察到有新的suggestion创建,产生相应的suggestion pod,该pod拉取用户的算法镜像(要求该镜像实现一个grpc服务,并且监听指定端口、遵循平台协议)。

 

该pod接受experiment的请求并回复算法产生的hyper parameters,更新suggestion object。

3)创建训练实例(trial)

 

experiment controller创建完算法后,由于刚开始没有任何trial,experiment controller会更新suggestion object的request,要求suggestion产生hyper paramters,并根据新的hyper paramters创建trials。trials controller会根据trials object创建mpijob

 

同时mpijob webhook会截取到该mpijob的创建请求,访问ts校验额度,创建相应实例。

4)训练实例的状态更新

 

创建状态->训练状态:mpijob训练实例产生后,会产生相应pod,并运行训练程序。pod webhook截取该pod的创建请求,增加metrics sidecar容器。metrics sidecar会读取用户的训练结果(要求用户训练程序将训练结构以指定格式写到写到指定文件),上报给db-manager存储。

 

训练状态->结束状态:mpijob训练完成后,trial会watch到,并从db-manger中获取训练结构、更新trial object状态。trial object状态变化会反映到experiment controller, 以促成下一轮hyper parameters的产生。即转到step 3的逻辑

5) 实验结束

 

当experiment观察到某一个trial的训练结果达到目标或者运行了指定数目的trial之后,实验结束并更新experiment状态。

 

三、如何开发自己的搜索算法

 

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的超参数作为最终的超参。

Be First to Comment

发表评论

电子邮件地址不会被公开。 必填项已用*标注