Press "Enter" to skip to content

AutoML框架概览

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

今天来闲聊一下之前看过的一些 autoML 框架。对于 autoML 偏理论部分的阐述,可以参考我之前的专栏文章:

字节:走马观花AutoML ​ zhuanlan.zhihu.com

AutoGluon

 

第一次了解到 AutoGluon 是在知乎的这个问题 中,当时感觉整体的架构设计非常清晰,而且针对业务领域来做相对“垂直”的 autoML,感觉是一个目前非常 practical 的方向。不过当时主要任务专注在 CV 和 NLP 方面,所以我们并没有深入试用。

 

第二次在 ICML 2020 的 autoML workshop 上看到 Alex 介绍 AutoGluon Tabular ,看测试效果相当惊人,几乎是碾压其它 autoML 框架如 auto-sklearn,TPOT,H2O AutoML,GCP-Tables 等。

于是我们赶紧装上了 AutoGluon,在几个业务场景中试用了一下。发现效果相当不错,可以比我们手调的单 lgb/catboost 模型还要再提升 1-2 个百分点,当然运行时间上要长不少。AutoGluon 是如何做到如此优异的性能表现呢?

 

框架特性

 

经过一番简单的源码与论文阅读,发现 AutoGluon Tabular 的几个特点:

 

 

    1. 不像其它框架专注于超参搜索优化,AutoGluon 更倾向于使用多模型的 ensemble,利用多层 stacking + k-fold bagging 来实现更好更稳定的模型效果。当然,AutoGluon 的其它任务中主要还是用的超参优化,所以这块的能力还是完全具备的。

 

    1. 在基础模型的选择上,包含了在各种表格类数据比赛中表现优异的梯度提升树模型,而没有一味的追求高大上的深度学习模型,非常务实。

 

    1. 针对表格类数据,对神经网络模型也做了针对性的优化,比如加入了针对类别变量的 embedding,利用 skip-connection 来进一步提升模型训练等。这里插个题外话,目前我们测试下来在 tabular 数据上表现较好的深度学习模型,一般都是通过各种形式来“模拟”梯度提升树模型的一些特性,同时有效利用深度学习做表达学习的一些长处,来最终实现能够 pk GBDT 模型的效果,典型案例如 TabNet,TFT 等。

 

    1. 对于表格数据来说,特征工程在很多情况下重要度都远高于模型调优,AutoGluon 也自带了一系列的特征工程自动化组件,例如各种缺失值的预处理,日期特征,类别特征,文本特征处理等。当然作为一个通用框架,这块的功能总体来说还是比较基础。

 

    1. 除了模型效果的优化外,AutoGluon 还支持了一系列针对部署时优化的操作,例如通过 inference 的开销信息,来重新构建一些更小的模型 ensemble,让用户根据预测时的性能要求来进行模型的挑选。在全量数据上训练各个子模型,来替代 k-fold bagging 形成的多模型,提升 inference 的性能。甚至还引入了模型蒸馏来进一步减小模型复杂度。

 

    1. 支持 BOHB 这类相对高级的搜索策略,不过 tabular 任务中好像还不能用,我猜应该是用了大量非 NN 模型导致 multi-fidelity 需要很多额外工作来实现吧。

 

 

当然也有些小问题:

 

 

    1. 代码整体的工程化考量感觉一般,有很多几千行的大文件和上百行的方法,比较难看懂其 API 层级抽象,对使用者来说,当高层 API 没法满足需求时,如何方便灵活的使用中低层的接口就会成为挑战。同样对于贡献者来说,需要入门理解内部的复杂逻辑门槛也相对较高。

 

    1. 虽然支持分布式的执行,不过看起来还比较简单。比如需要用户自己管理代码,运行环境以及数据在多个节点的分发。虽然分布式在目前看不是一个特别大的需求,但未来结合云计算来实现弹性的优化任务执行应该会是一个趋势。AutoGluon 在当前的架构中好像比较缺少对容器化调度,流行的分布式数据存储,以及分布式模型训练等方面的支持。

 

 

代码样例

 

具体的代码 tutorial 可以参考这个官方文档。大致的 API 使用体验如下:

 

先来看下超参搜索空间定义这块,基本上大家都是类似的写法。

接下来开始具体的 autoML 优化过程,基于 TabularPredictor 类做一系列的 fitpredict 操作。

最后这块就比较有特色了,包括 autoML 模型的解释,部署优化等。

总结

 

总体来看,AutoGluon 框架的底层设计,优化效果,和整体的 vision 都很不错,从最近的几个 release 来看 tabular 任务也持续有大量的优化改进,非常值得做结构化数据的同学们尝试。

 

此外,在非 tabular 问题上,AutoGluon 也很强大,例如针对 CV,NLP 任务的优化 predictor,预训练的 model zoo,对强化学习的支持,ENAS 的支持 等等。这方面本人的经验较少,就不班门弄斧了。

 

一句话点评:目前最好的 domain specific autoML 框架方案。

 

Optuna

 

第一次听说 autoML 框架,印象中还是在 14-15 年的某几个 Kaggle 比赛中。当时大家比较习惯使用的超参优化工具一般是 hyperopt 或者 BayesianOptimization 这类传统参数搜索工具,基本都是专注于参数搜索优化的小工具。后来随着这个方向的发展壮大,出现了很多新框架在用户友好性,框架结合,场景化等方面做了各种改进和包装。这其中 Optuna 就是一个给我留下很深印象的一款框架。

 

框架结合

 

Optuna 的框架结合做的非常好,第一次看到下面的 sample 代码时简直令我震惊:

上面这串代码,如果不仔细看还以为就是在跑原生的 lightgbm,基本只改了一个 import,就成了一个自动搜参的 lightgbm!它背后会具体执行:

也是一个经验固化的调优 pipeline,不过事实上可以推广到各种不同模型的调优思路总结,比如 NN 应该先调学习率,batch size,再调网络结构,然后再精细化调整一下学习率等(欢迎有经验的同学 comment)。

 

高效搜参

 

虽然很多研究中都提到了 Successive Halving,Hyperband,Multi-fidelity 优化等提高搜索效率的手段,但真正在产品框架中做了很好实现的,Optuna 是我发现的第一家。只需要加个参数,就能实现在训练过程中提前终止那些看起来表现不好的参数组合,节省大量的搜参时间:

上面的搜参过程会在经过设定的 warm up 阶段后,针对每一组搜索的参数做定期的评估。比如训练 10 轮后,评估一下模型效果,如果发现比历史模型的表现中位值更差,就提前终止训练。

 

如果是自定义的模型,只要能支持增量训练(比如 NN 按照 epoch 来训练,树模型按照 boost round 来训练),就可以在训练过程中实现相应的 pruning 机制:

在实际使用过程中,使用 pruning 机制对于我们的搜索速度有成倍的效率提升,非常好用。

 

灵活的搜参空间定义

 

Optuna 还有一个很不一样的功能点在于动态定义搜索空间。例如我们在构建 NN 模型时,想动态决定一共构建多少层 MLP,以及每一层的神经元数量,如果用 hyperopt 之类的框架就不太容易实现。而用 Optuna,则可以直接用 Python 的循环,逻辑判断语句来生成:

在这个基础上,我们甚至可以对整个 pipeline 的结构做灵活的搜索调整,比如看是否做数据的 categorical encoding,是否做 label transform,以及对应的用什幺方法来转换等。

 

其它特性

 

Optuna 也支持分布式的优化执行,主要通过存储层(比如 MySQL db)来进行各个 trial 信息的记录和同步,实际执行中对于代码来说几乎没有什幺“侵入性”。而对于资源管理,调度执行等方面的问题,都交给其它框架(例如 K8s,Ray)去解决,不失为一种相当简洁优雅的实现。当然缺点就是搜索上的调度,资源限制等就无法自行管理,比较简单的例子是如果你在一台 8 核机器上开 2 个使用 8 个 thread 训练的 lightgbm 的话,2 个任务都可能因为资源争抢而长时间无法完成。

 

此外,Optuna 也开始引入了 dashboard 来展现优化过程的各类信息,便于用户来分析各个超参数对模型效果的影响等。

总结

 

Optuna 作为新世代的 autoML 工具,非常适合轻量级的模型参数优化与分析场景。其灵活的搜索空间定义,也很方便用户在此基础上来构建垂直场景的整体 pipeline 优化框架。

 

一句话点评:如果只想要一个快速灵活的调参工具,就选 Optuna。

 

TPOT

 

TPOT 也跟 hyperopt 等属于比较早期的 autoML 框架,不过它没有采用常见的贝叶斯优化方法做超参优化,而是使用了遗传算法来做整体 pipeline 的生成优化。这个库在刚出来时我们尝试了一波,发现运行速度比较慢,而且整体的效果也并不理想,所以后续并没有深入使用。不过它的一些设计特性还是值得了解一下:

 

 

    1. 总体的流程是定义了一系列操作符和参数空间,然后根据定义的 template 来生成初代的 pipeline,接着通过

deap

    1. 这个库来做具体的 pipeline 遗传算法优化。具体可以参考这篇

介绍 TPOT 原理的知乎文章

 

    1. 使用遗传算法的一个优势是 pipeline 的长度和结构可以是非常灵活的,而传统的优化方法一般都是在一个固定的 pipeline 结构上做参数优化。

 

    1. 在 pipeline 优化完成后,TPOT 支持 export 为 Python 代码,用户可以在此基础上进一步做分析与优化。最近 Databricks 推出的 autoML 工具也主打这个 glassbox 的概念,可以把人工调优与 autoML 更好的结合起来。

 

    1. 在分布式执行的支持上,主要利用了

dask

    1. 来实现 sklearn pipeline 的并行化。

 

当然采用这种灵活的 pipeline 生成优化方案,在效率上的挑战还是比较大的,很多时候模型优化事实上只在一个很小的 sub-space 上的表现会比较好,人工经验形成的 pipeline 模板基本也够用。如果能实现遗传算法的增量训练,那幺或许可以在 TPOT 基础上与 Hyperband 之类的技术进行结合,来提升效率,但是 preprocessing 部分的开销仍然无法节约。

 

另外 TPOT 的整体代码风格上也比较随意,不像是工业界的成熟作品,理解起来会有点困难。

 

一句话点评:可变 pipeline 的构建和代码生成值得学习。

 

Ray Tune

 

框架特性

 

Ray 是一个当下非常火热的分布式计算框架,而 Tune 是基于 Ray 来实现的 autoML 框架。比起前面的几个框架来说,Ray Tune 绝对算是分布式 autoML 的正规军了。不过我们的日常应用中需要用到大规模 autoML 优化的场景不多,所以也没有多少 Ray Tune 的使用经验,仅从文档和代码的阅读出发来聊聊个人感受。

 

    1. Ray Tune 的结构设计上与 AutoGluon 有很多类似之处,比如像 Hyperband 这类搜索策略都放到了

scheduler

    1. 模块里进行实现,而参数的选择放在了

searcher

    1. 模块中来实现。这个抽象还是比较清晰的,可以很方便的在两个模块中做单独的扩展,例如 Ray Tune 的

scheduler

    1. 中实现了很多高级算法,包括 async hyperband,population based training(来自 DeepMind 的工作)等。同理在

suggest

    1. 模块中,Ray Tune 对接了很多成熟的超参优化库,如 hyperopt,optuna,skopt,dragonfly,ax,HpBandSter,hebo 等等,看完才知道原来有这幺多的超参优化库……

 

    1. Ray Tune 跟 Optuna 类似,在跟各种框架的结合上也下了不少功夫,例如对主流训练框架 Lightgbm,PyTorch,PyTorch Lightening,Keras,Horovod 等的支持,训练过程的 checkpointing 与 tensorboard 的对接,实验结果的记录也支持 MLflow 和 wandb,还包括底层架构 K8s,Docker 的对接支持等。

 

    1. Ray Tune 在优化过程中的容错处理也相对更加完善,可以中途停止搜索,后续再继续优化,也可以在 Spot instance 集群上执行大规模的训练任务,节省计算成本。可以参考 BAIR 的这篇 blog。

 

    1. Ray 本身的生态环境日渐成熟强大,例如数据处理方面 Dask, Modin 都可以在 Ray 上获得“分布式 Pandas”的使用体验,Ray Serve 支持 Python 类服务的部署,RLlib 支持在 Ray 上跑分布式的强化学习任务等等。相比 Spark,感觉 Ray 在数据科学全链路上的完整性一致性体验更好,吸引了更多数据应用工作者的加入使用。

 

 

代码样例

 

我们也来看几个 Ray Tune 上有意思的代码案例。

 

Ray Tune 中的高级算法支持,华为诺亚方舟实验室的河伯框架:

在 Trainable 中需要实现 save/load checkpoint,用以支持分布式训练容错:

使用 callbacks 来支持 MLflow, WandB 的对接,这个结果展示就比简单的 fit summary 丰富多啦:

如果想要了解整体的集群 setup 使用流程,可以参考官方文档 或者这篇 blog。

 

总结

 

从上面的代码案例中可以看到,在 Ray Tune 中定义 Trainable 还是一件有点麻烦的事情,也就是对用户代码的侵入性有点强。另外 Ray 跟 K8s 的集成总体来说有点别扭,Raylet + Object Store 的设计导致很难直接利用底层抽象 infra 来做 auto scaling,同时对于具体任务的执行也基本限定在 Python 语言体系中。在未来云原生时代,Ray 框架的发展不知是否会受到一些影响。

 

一句话点评:当前分布式 autoML 的最佳选择。

 

Katib

 

Katib 感觉就是为了解决一些 Ray 的一些问题而诞生的真正的云原生超参优化框架。具体的介绍可以参考高策哥哥的这篇文章。从文中看,Katib 相对于 Ray Tune 来说有两大改变,一是支持多租户,二是完全云原生的架构。多租户可能关心的同学并不多,我们主要来看看什幺是云原生的架构。

 

云原生机器学习

 

对于云原生,大家第一反应是用上了 K8s 来跑任务就是云原生了!比如我们想在 K8s 集群上跑一个 tensorflow 的分布式训练任务,只需要把训练代码打包进 image 中,再用 K8s 来启动多个 Job 类型的任务来执行训练即可。但这个 K8s 的任务配置会有点麻烦,比如要在 yaml config 里考虑各个 worker,parameter server 的地址和端口配置,如果节点数量变化,还需要修改对应的配置文件等(顺带一提,从用户角度看,同样的任务在 Ray 上面跑感觉就简单了很多)。

而更加“云原生”的做法,是把这些逻辑封装起来,开发针对这个场景的 K8s CRD,而对于用户来说,只需要简单的在一个 yaml 文件中声明即可。推荐阅读陈震老师的这篇文章,了解更多的背后细节。

在 Katib 中,Experiment, Suggestion, Trial 和 TrialJob 都是通过 CRD 的方式来实现的,因而也就可以直接利用 K8s 的各种调度,监控,日志收集,容错等等方面的能力,成为目前最“云原生”的 autoML 框架。例如对于 Suggestion,Katib 会启动相应的 Suggestion service 和 pod,其中运行用户定义的参数选取算法。开发者完全可以使用不同语言来实现,非常的灵活。

代码样例

 

作为用户,我们也来体验一下在 Katib 中跑一个 autoML 任务的配置:

可以看到我们把各种搜索空间,优化算法的定义都放到了 yaml 里(感觉动态搜索空间会比较难实现),然后通过 K8s Experiment, Trial 来进行具体计算优化。在容器执行训练脚本中,的确不需要引入 Katib 相关的包或者代码,感觉上“侵入性”的确低了很多,而且使用 yaml 这类声明式的代码,对于用户来说上手成本低了不少。但是进一步体验了下相关的文档和案例,感觉还是有不少吐槽点:

 

 

    1. 对于训练结果的收集,Katib 用了

sidecar 容器

    1. 来进行收集,不过具体的指标打印,格式配置这些还是需要用户来处理。同理对于训练脚本来说,会需要有大量的代码来处理命令行参数对接模型训练。这些在我看来都属于“侵入性”,起码对开发者造成了一定的心智负担。

 

    1. 构建容器,撰写 yaml 这些也需要大量的工作,对于不熟悉 K8s, Docker 生态的算法工程师来说上手难度要高的多。看了下 Python SDK 和对应的 notebook 示例,感觉整体使用的复杂度还是相当高。

 

    1. Kubeflow 本身的搭建成本也比较高,进一步提高了使用门槛。

 

    1. 对于最终用户来说,云原生架构目前能带来的直观的回报并不明显,好像并没有解决什幺“核心痛点”。退一步来说,容器化本质上还是为了解决稳定的部署和运行问题,这天然和算法的探索性实验性有一定矛盾,如何找到一个平衡点是需要深入思考的。

 

 

所以总体来看,现阶段如果需要做分布式 autoML,个人还是更倾向选择 Ray Tune。

 

一句话点评:代表未来的云原生 autoML 框架

 

nni

 

最后再来看下微软的 nni,从项目的名字可以看出这个框架主要的重心还是在优化神经网络类的模型方面,而且整体的定位是偏通用框架方向。

通过文档了解了一下 nni 的特性,发现主要在几个方面比较突出:

 

 

    1. 在 NAS 方面下了很大的功夫,比如在 2.0 版本中引入了新的 Retiarii 框架,提升了 NAS 任务的抽象化与模块化,并对训练过程也有很大的性能提升。

 

    1. 在模型压缩方面也走在前列,提供了非常多的自动优化方法。

 

    1. 实现了非常多的优化算法可供选择,也是目前看到的唯一一家在 early stopping 中实现了 curve fitting 的框架。

 

    1. 底层执行框架方面的支持也很丰富,包括 local,remote,OpenPAI,Azure ML,Kubeflow 等等。

 

    1. 整体产品化做的很好,文档写的非常完善,一看就是花了不少功夫。工程代码质量也不错,很有大厂风范。

 

 

整体感觉非常综合全面,值得深度使用 NN 模型的同学使用。官方也经常在知乎,B站上做宣传,可以关注一下,比如这篇回答。

 

一句话点评:NN 模型的最佳 autoML 通用框架

 

框架思考

 

看了这幺多框架,最后也想聊一聊一些 autoML 方向性问题的思考。

 

autoML 要解决什幺问题?

 

从大家普遍的认知来看,在算法项目中,绝大部分的效果提升都来自数据方面的调整和处理,如果只是单纯的超参调优,可以获得的提升十分有限,基本都是 5%以内。虽然大家都在说 autoML 可以节省工程师调参的时间,但实际上当前大多数框架专注解决的问题不是算法工程师花费最多时间的问题。要真正实现建模的自动化,还有很多更重要和困难的问题需要去解决。

 

大规模优化的需求有多大?

 

看到有不少框架在分布式训练和优化,NAS 等方向上投入了很多,但这些问题背后的市场有多大?比如最近的一些研究发现 MLP 就能在很多问题上达到不错的效果了,那幺是不是我们更应该把精力放在数据提升而不是 NAS 上?对于像 GPT3 这种量级的大模型,未来是每家公司都要自行训练,还是有几个领域通用模型来 fine-tune 就可以?

 

未来的模型开发流程

 

在我们已经拥有了一些成熟的 autoML 框架后,模型开发的流程会有什幺样的改变?在准备完数据,跑完一轮 autoML 优化之后,我们得到了一个 auc 为 0.75 的模型 pipeline,那幺下一步我们能否直接部署这个模型,还是需要继续优化?优化的方向和方法会是什幺,能否进一步提升后续迭代中的自动化程度呢?

 

Data-centric autoML

 

目前已知的一些在自动化数据处理,特征工程方面的框架看起来都没有形成太大的影响力,一个可能的原因是大部分的数据问题都跟业务领域有很深的绑定关系,很难形成通用的自动化解决方案。但我们还是有机会形成一些垂直领域的自动化特征方案,或者在通用层面上实现很多从数据分析角度出发的自动化诊断和处理功能。未来这个方向应该会越来越受到重视。

 

云原生对 autoML 的影响

 

Katib 是第一个以云原生的概念打造的 autoML 系统,但目前所能带来的收益感觉并不明显,加上使用方式上与传统 autoML 框架的不同导致接受程度仍然比较低。如果能基于 Spot instance 或者其它低成本计算资源来进行 autoML 优化,并在有需要的时候可以以更高的价格切换到高性能 autoML 执行,是不是有可能为客户提供更直接的价值感受?

Be First to Comment

发表评论

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