本章内容包括:

  • 界说作业流和作业流编列
  • 深度学习体系为何需求支撑作业流
  • 规划通用的作业流编列体系
  • 介绍三个开源的编列体系:Airflow、Argo Workflows和Metaflow

在本章中,咱们将评论深度学习体系中最后但至关重要的一部分:作业流编列。作业流编列是一种办理、履行和监控作业流主动化的服务。作业流是一个笼统且广泛的概念,它实质上是一系列操作的序列,这些操作是某个更大使命的一部分。假如您能够制定一套使命来完结一项作业,那么这个计划便是一个作业流。例如,咱们能够为练习机器学习(ML)模型界说一个次序作业流。这个作业流能够由以下使命组成:获取原始数据、重建练习数据集、练习模型、评价模型和布置模型。

由于作业流是一个履行计划,它能够手动履行。例如,数据科学家能够手动完结咱们刚刚描绘的模型练习作业流中的使命。例如,要完结“获取原始数据”使命,数据科学家能够编写网络恳求并发送给数据集办理(DM)服务来获取数据集,一切这些都不需求工程师的协助。

然而,手动履行作业流并不理想。咱们期望主动化作业流的履行。当有许多为不同意图开发的作业流时,咱们需求一个专门的体系来处理作业流履行的杂乱性。咱们将这种体系称为作业流编列体系。

作业流编列体系被规划用于办理作业流的生命周期,包括作业流的创立、履行和毛病扫除。它不只供给了坚持一切计划代码运转的脉息,还供给了一个操控平面,供数据科学家办理深度学习体系中的一切主动化操作。

在本章中,咱们将评论作业流编列体系的规划以及在深度学习范畴中运用最广泛的开源编列体系。经过阅览本章,您不只将对体系需求和规划选项有扎实的了解,还将了解怎么挑选最适合您自己状况的适宜的开源编列体系。

介绍作业流编列

在咱们深入评论作业流编列体系规划的细节之前,让咱们先扼要评论一下作业流编列的基本概念,特别是从深度学习/机器学习的视点看作业流的特殊应战。

留意,由于在深度学习项目和机器学习项目中运用作业流编列的要求几乎是相同的,所以在本章中,咱们将深度学习和机器学习这两个词交换运用。

什么是作业流?

一般来说,作业流是一个由一系列操作组成的使命。作业流能够被看作是一个有向无环图(DAG),其中每个进程是最小的可恢复核算单元,描绘了一个动作,例如获取数据或触发一个服务。每个进程要么成功完结,要么彻底失利。在本章中,咱们将使命(task)和进程(step)交换运用。

DAG指定了进程之间的依靠联系和履行次序。图9.1显示了一个用于练习自然语言处理(NLP)模型的示例作业流。

从图9.1中的示例DAG能够看出,作业流由许多进程组成。每个进程依靠于另一个进程,实线箭头表明进程之间的依靠联系。这些箭头和进程形成了一个没有循环的作业流DAG。

《设计深度学习系统》第九章:工作流编排

假如依照DAG中的箭头(从左到右)进行操作并完结使命,您能够练习并发布一个NLP模型到出产环境中。例如,当一个传入恳求触发作业流时,授权(authorization)进程将首要被履行,然后一起履行数据集构建进程和嵌入获取进程。箭头的另一侧的进程将在这两个进程完结后履行。

作业流在IT职业中被广泛运用。只需您能够将一个进程界说为一系列单个使命/进程的DAG,这个进程就能够被以为是一个作业流。作业流关于深度学习模型开发至关重要。实践上,在出产环境中,大多数深度学习模型构建活动都以作业流的方法出现和履行。

留意:作业流不该该有循环。为了保证作业流能够在任何状况下完结,其履行图有必要是一个DAG,以防止作业流履行堕入死循环。

什么是作业流编列?

一旦咱们界说了一个作业流,下一步便是运转作业流。运转作业流意味着依据作业流的DAG中界说的次序履行作业流进程。作业流编列是咱们用来描绘作业流的履行和监控的术语。

作业流编列的方针是主动化履行作业流中界说的使命。在实践中,作业流编列的概念一般扩展到整个作业流办理范畴,包括以主动化的方法创立、调度、履行和监控多个作业流。

为什么深度学习体系需求作业流编列?理想状况下,咱们应该能够将整个深度学习项目编写为一个整体。这正是咱们在项意图原型规划阶段所做的,将一切的代码放在一个Jupyter笔记本中。那么,为什么咱们需求将原型规划的代码转化为作业流,并在作业流编列体系中运转呢?答案有两个方面:主动化和作业同享。为了了解这些原因,让咱们来看一下图9.2中的三个示例练习作业流。

《设计深度学习系统》第九章:工作流编排

运用作业流的一个巨大长处是将大块的代码转化为一组可同享和可重用的组件。在图9.2中,咱们设想了三名数据科学家分别在三个模型练习项目(A、B和C)上作业。由于每个项意图练习逻辑不同,数据科学家开发了三个不同的作业流程(A、B和C)来主动化他们的模型练习进程。虽然每个作业流程具有不同的DAG,但每个DAG中的进程高度堆叠。总共的六个进程是可同享和可重用的。例如,auth进程(进程1)是一切三个作业流程的第一步。

具有可重用的进程能够极大进步数据科学家的出产力。例如,要从DM服务中提取数据(图9.2中的进程2),数据科学家需求学习DM网络API的作业方法。可是,假如已经有人将DM数据提取办法构建为一个进程函数,科学家们能够在他们的作业流程中直接重用这个进程,而无需学习怎么与DM服务进行交互。假如每个人都以作业流的方法编写项目,咱们将具有许多可重用的进程,这将在组织层面上节约许多重复的作业!

作业流之所以适用于深度学习开发的另一个原因是它促进了协作。模型开发需求团队合作;一个专门的团队或许担任数据,而另一个团队担任练习算法。经过在作业流程中界说一个杂乱的模型构建进程,咱们能够将一个杂乱的大型项目分解为不同的部分(或进程),并将它们分配给不同的团队,一起坚持项目有序和组件的正确次序。作业流DAG清楚地显示了一切项目参与者所见的使命依靠联系。

简而言之,一个好的作业流编列体系鼓舞作业同享,促进团队协作,并主动化杂乱的开发场景。一切这些长处使得作业流编列成为深度学习项目开发的要害组成部分。

深度学习中运用作业流编列面临的应战

在前面的部分中,咱们看到作业流体系怎么为深度学习项目开发供给了许多长处。可是有一个留意事项:运用作业流来原型化深度学习算法的主意是繁琐的。

为了了解为什么会繁琐以及为什么会繁琐,让咱们看一下深度学习开发进程的图表(图9.3)。这个图表应该为你了解作业流在深度学习环境中带来的应战奠定根底。

《设计深度学习系统》第九章:工作流编排

在图9.3中,咱们能够看到一个从数据科学家的视点来看的典型深度学习项目开发进程。该进程能够分为两个阶段:本地孵化阶段和出产阶段。

在本地孵化阶段,数据科学家在他们的本地/开发环境中进行数据探索和模型练习的原型制造。当原型制造完结而且项目看起来有期望时,数据科学家开端进行出产布置:将原型代码移植到出产体系中。 在出产阶段,数据科学家将原型代码转化为作业流。他们将代码分解为多个进程,并界说一个作业流DAG,然后将作业流提交给作业流编列体系。之后,编列体系接管并依据其计划运转作业流。

原型制造和出产之间的距离

假如你问一个从事作业流编列体系的工程师对图9.3中的开发进程的观点,答案很或许是:还不错!但在实践中,这个进程对数据科学家来说是有问题的。

从数据科学家的视点来看,一旦算法在本地测验经过,其原型代码应该当即交给到出产环境中。但在图9.3中,咱们能够看到原型制造阶段和出产阶段之间并没有平稳的衔接。将孵化代码交给到出产环境并不直观;数据科学家有必要额定作业来构建一个作业流,在出产环境中运转他们的代码。原型代码与出产作业流之间的距离对开发速度有两个方面的影响:

  • 作业流的构建和调试并不直观:数据科学家在编写模型练习作业流时一般面临巨大的学习曲线,需求学习作业流DAG语法、作业流库、编码范式和毛病排查等知识。作业流的毛病排查是最令人痛苦的部分。大多数编列体系不支撑本地履行,这意味着数据科学家有必要在远程编列体系中测验他们的作业流。这很困难,由于作业流环境和作业流履行日志都是远程的,所以当作业流履行犯错时,数据科学家不能轻易地找出根本原因。
  • 作业流的构建不只仅是一次性的:人们常常过错地以为,作业流的构建只产生一次,所以即便耗时吃力也没联系。但事实是,作业流的构建是继续产生的,由于深度学习开发是一个迭代的进程。正如图9.3所示,数据科学家不断地进行原型制造和出产试验的迭代,因而作业流需求常常更新,以测验从本地到出产环境的新改善。因而,令人不愉快且耗时的作业流构建会反复产生,阻止了开发速度。

滑润过渡从原型制造到出产

虽然存在距离,图9.3中的流程是很好的。数据科学家从一个直观的脚本开端进行原型制造,然后继续作业。假如每次迭代后的结果满意有期望,那么“直观的本地脚本”将被转化为作业流,并在出产环境中运转。

要害的改善在于使原型代码到出产作业流的过渡进程无缝衔接。假如一个编列体系专为深度学习场景规划,它应该供给东西来协助数据科学家以最小的作业量从他们的代码构建作业流。例如,Metaflow是一个开源库,将在9.3.3节中评论,它答应数据科学家经过编写带有Python注解的Python代码来授权作业流。数据科学家能够直接从他们的原型代码中获得一个作业流,而无需进行任何更改。Metaflow还在本地和云出产环境之间供给一致的模型履行用户体会。这消除了作业流测验中的冲突,由于Metaflow在本地和出产环境中以相同的方法操作作业流。

规划一个流程编列体系

在本节中,咱们将分三个进程来规划作业流编列体系。首要,咱们将运用一个典型的数据科学家用户场景,展现编列体系从用户视点的作业方法。其次,咱们学习通用的编列体系规划。第三,咱们总结构建或评价编列体系的要害规划准则。经过阅览本节内容,您将了解编列体系的一般作业原理,然后能够自傲地评价或运用任何编列体系。

用户场景

虽然作业流程的进程在不同的场景下有很大的差异,但关于数据科学家来说,用户场景是相当标准的。大多数作业流运用能够分为两个阶段:开发阶段和履行阶段。请参阅图9.4,了解数据科学家Vena的作业流用户体会。让咱们一步一步地跟从图9.4中Vena的用户场景进行说明。

《设计深度学习系统》第九章:工作流编排

开发阶段

在开发阶段,数据科学家将他们的练习代码转化为作业流。以下是Vena的示例:

  1. Vena是一位数据科学家,她在本地环境中运用Jupyter笔记本或纯Python原型化她的模型练习算法。经过本地测验和评价后,Vena以为现在是将代码布置到出产环境中进行实时试验的时分了。
  2. 由于在出产环境中运转的一切内容都是作业流,所以Vena需求将她的原型代码转化为作业流。因而,Vena运用作业流编列体系供给的语法将她的作业重建为一个使命DAG,并将其装备在一个YAML(文本装备)文件中。例如,数据解析 -> 数据增强 -> 数据集构建 -> 练习 -> [在线评价,离线评价] -> 模型发布。
  3. Vena为DAG中的每个进程设置输入/输出参数和操作。以练习进程为例,Vena将进程操作设置为RESTful HTTP恳求。该进程将向模型练习服务发送一个RESTful恳求来发动一个练习作业。此恳求的有效载荷和参数来自于进程的输入参数。
  4. 作业流界说完结后,Vena在DAG YAML文件中设置作业流的履行计划。例如,Vena能够将作业流组织在每个月的第一天运转,并设置作业流由外部事情触发。
  5. Vena进行本地验证并提交作业流给编列服务。

为了让您了解作业流在实践中的含义,以下代码展现了Vena的一个伪代码作业流(在第9.3节中,咱们将评论实践的作业流体系):

# define workflow DAG
with DAG(
 description='Vena’s sample training workflow',
 schedule_interval=timedelta(months=1),
 start_date=datetime(2022, 1, 1),
 ) as dag:
  # define execution logic for each step
 data_parse_step = BashOperator( .. .. ..)
 data_augment_step = BashOperator( .. .. ..)
 dataset_building_step = BashOperator( .. .. ..)
 training_step = BashOperator( .. .. ..)
  # Declares step dependencies
  data_parse_step >> data_augment_step
  >> dataset_building_step >> training_step

履行阶段

在履行阶段,编列服务履行模型练习作业流,就像Vena的示例一样:

  1. 一旦Vena的作业流被提交,编列服务将作业流DAG保存到数据库中。
  2. 编列服务的调度器组件检测到Vena的作业流,并将作业流的使命分派给后台作业节点。调度器将保证使命依照作业流DAG中界说的次序履行。
  3. Vena运用编列服务的Web界面实时检查作业流的履行进展和结果。
  4. 假如作业流生成了一个好的模型,Vena能够将其推行到预发布和出产环境。假如不是,则Vena开端另一次原型化迭代。

判断一个编列体系是否适用于深度学习的要害目标是将原型化代码转化为作业流的难易程度。在图9.4中,咱们看到每逢Vena原型化一个新的主意时,她都需求将练习代码转化为作业流。假如咱们能减少将深度学习代码转化为作业流的难度,能够想象节约的人力时刻将会有多大。

留意:作业流应该一直坚持轻量级。作业流用于主动化一个进程,其方针是将一系列使命进行分组和衔接,并依照界说的次序履行。运用作业流的重要长处是人们能够同享和重用使命,然后更快地主动化他们的进程。因而,作业流自身不该进行任何繁重的核算,真实的作业应由作业流中的使命完结。

一个通用编列体系规划

现在让咱们转向通用的作业流编列体系。为了协助您了解编列体系的作业原理并研讨开源编列体系,咱们预备了一个高级体系规划。经过扩大详细完成细节并仅保存中心组件,这个规划适用于大多数编列体系,包括将在第9.3节中评论的开源体系。请参阅图9.5的规划提案。

《设计深度学习系统》第九章:工作流编排

一个作业流编列体系一般包括以下五个组件:

  • Web服务器:Web服务器供给Web用户界面和一组Web API,供用户创立、检查、触发和调试作业流的行为。
  • 调度器和操控器:调度器和操控器组件有两个功用。首要,调度器监督体系中的每个活动作业流,并在恰当的时分组织作业流运转。其次,操控器将作业流使命分派给作业节点。虽然调度器和操控器是两个不同的功用单元,但它们一般一同完成,由于它们都与作业流的履行相关。
  • 元数据数据库:元数据数据库存储作业流的装备、DAG、修改和履行前史,以及使命的履行状况。
  • 作业节点组:作业节点组供给核算资源来运转作业流使命。作业节点笼统了根底设施,而且对正在运转的使命是无关的。例如,咱们或许有不同类型的作业节点,比方Kubernetes作业节点和亚马逊弹性核算云(EC2)作业节点,但它们都能够履行相同的使命,虽然在不同的根底设施上运转。
  • 目标存储:目标存储是一切其他组件同享的文件存储;它一般建立在云目标存储(例如亚马逊简略存储服务S3)之上。目标存储的一个用处是使命输出同享。当一个作业节点运转一个使命时,它从目标存储中读取上一个使命的输出值作为使命的输入;作业节点还将使命的输出保存到目标存储中,以供后续使命运用。

目标存储和元数据数据库对编列体系的一切组件都是可拜访的,包括调度器、Web服务器和作业节点的组件。经过会集存储数据,中心组件能够解耦,使得Web服务器、调度器和作业节点能够独立作业。

作业流是怎么履行的?

首要,Vena界说作业流的DAG。在DAG内部,Vena声明了一组使命并界说了使命履行次序的操控流程。关于每个使命,Vena能够运用体系的默认运算符(例如Shell指令运算符或Python运算符),或许构建自己的运算符来履行使命。

其次,Vena经过Web界面或指令行将作业流(包括依靠代码)提交给Web服务器。作业流被保存在元数据数据库中。

第三,调度器守时(每几秒或几分钟)扫描元数据数据库,并检测新的作业流;然后在预定的时刻发动作业流。为了履行作业流,调度器调用操控器组件,依据DAG中界说的使命序列,将作业流的使命分派到作业行列中。

第四步,作业节点从同享的作业行列中获取一个使命;它从元数据数据库中读取使命界说,并经过运转使命的操作符履行使命。在履行进程中,作业节点将使命的输出值保存到目标存储中,并将使命的履行状况报告给元数据数据库。

最后但同样重要的是,Vena运用保管在Web服务器组件上的Web用户界面来监督作业流的履行。由于调度器/操控器组件和作业节点实时向元数据数据库报告状况,因而Web用户界面一直显示最新的作业流状况。

作业流编列规划准则

由于咱们已经了解了作业流编列体系的内部和外部作业原理,现在是时分审视使一个作业流编列体系在深度学习场景下脱颖而出的规划准则了。咱们期望您能够将这些准则作为指导,用于改善您的体系或评价开源办法。

留意,从工程视点来看,作业流编列体系是深度学习体系中最杂乱的组件之一,因而在开端的几个版别中,不必过于忧虑使您的体系与这些准则彻底匹配。

准则1:要害性

作业流编列本质上是一个作业调度应战,因而任何编列体系的底线都是供给安稳的作业流履行体会。有效的作业流应该能够正确、可重复地按计划履行。

准则2:易用性

在深度学习环境中,编列体系的易用性衡量标准在于它是否能进步数据科学家的出产力。大多数数据科学家与编列体系的交互都是创立、测验和监督作业流。因而,用户友好的编列体系应该让用户能够轻松地创立、监督和排查作业流。

准则3:可扩展性

为了满意各种各样的深度学习根底设施,人们应该能够轻松地界说自己的使命操作符和履行器,而不必忧虑它们布置在哪里。编列体系应该供给适合您环境的笼统等级,不管是Amazon EC2仍是Kubernetes。

准则4:阻隔性

要害的阻隔性包括两种:作业流创立阻隔和作业流履行阻隔。作业流创立阻隔意味着在创立作业流时,人们不能彼此干扰。例如,假如Vena提交了一个无效的作业流DAG,或许发布了一个被其他作业流引证的常用同享库的新版别,现有的作业流不该受到影响。

准则5:可扩展性

一个优异的编列体系应该处理以下两个可扩展性问题:处理许多并发的作业流和处理巨大的杂乱作业流。并发作业流的扩展性一般意味着在满意的核算资源下,例如向作业组增加更多的作业节点,编列体系能够处理无限数量的并发作业流履行。一起,体系应一直坚持每个作业流的服务等级协议(SLA)。例如,不管有多少其他作业流正在履行,作业流应该在其计划的时刻内履行,而且不晚于2秒。

关于单个大型作业流的扩展性,体系应鼓舞用户不用忧虑功用问题,以便专心于可读性好、简略明了的代码和易于操作。当作业流履行抵达某个约束时(例如,练习操作符履行时刻过长),编列体系应供给一些水平并行性操作符,例如分布式练习操作符,以处理单个作业流的功用问题。

深度学习编列的首要扩展思想是咱们应该在体系等级处理功用问题,而不是要求用户编写具有可扩展性意识的代码。这样能够防止下降代码的可读性,增加调试难度并增加运维担负。

准则6:以人为中心支撑原型和出产

将数据科学家的本地原型代码与出产作业流衔接起来是深度学习特有的要求。这是咱们评价编列体系是否适用于深度学习体系的要害目标。

为深度学习规划的编列体系将尊重从原型到出产的迭代式继续开发进程。因而,它将全力协助数据科学家将本地原型代码无缝转化为出产作业流。

开源计划

在本节中,咱们将介绍三个经过实战验证的作业流编列体系:Airflow、Argo Workflows和Metaflow。这三个开源体系在IT职业得到了广泛应用,而且有着活跃的社区支撑。除了对它们进行一般性的介绍,咱们还将从深度学习项目开发的视点评价这些作业流体系。

为了进行公平的比较,咱们将在Airflow、Argo Workflows和Metaflow中完成相同作业流的伪代码。基本上,假如有新的数据,咱们会首要对数据进行转化并将其保存到数据库中的新表中,然后告诉数据科学团队。此外,咱们期望作业流每天运转一次。

Airflow

Airflow(airflow.apache.org/docs/apache…)于2014年在Airbnb创立,并现在是Apache基金会的一部分。Airflow是一个用于以编程方法编写、调度和监控作业流的渠道。Airflow并非专为深度学习场景而规划,它开端是为了编列日益杂乱的ETL(提取、转化、加载)流水线(或数据流水线)而构建的。但由于Airflow具有杰出的可扩展性、出产质量和图形用户界面(GUI)支撑,它在许多其他范畴,包括深度学习,都得到了广泛应用。截至本书编撰时,Airflow是最受欢迎的编列体系。

典型的运用事例是在Airflow中构建作业流需求两个进程。首要,界说作业流的DAG和使命。其次,在DAG中声明使命之间的依靠联系。Airflow的DAG本质上是Python代码。请参阅以下示例,了解咱们的样例作业流在Airflow中的完成方法。

# declare the workflow DAG.
with DAG(dag_id="data_process_dag",
    schedule_interval="@daily",
         default_args=default_args, 
         template_searchpath=[f"{os.environ['AIRFLOW_HOME']}"],   
         catchup=False) as dag:
# define tasks of the workflow, each code section below is a task
is_new_data_available = FileSensor(
  task_id="is_new_data_available",
  fs_conn_id="data_path",
  filepath="data.csv",
    .. .. .. 
)
# define data transformation task
transform_data = PythonOperator(
  task_id="transform_data",
  python_callable=transform_data
)
# define table creation task
create_table = PostgresOperator(
  task_id="create_table",
  sql='''CREATE TABLE IF NOT EXISTS invoices (
            .. .. ..
      );''',
  postgres_conn_id='postgres',
  database='customer_data'
)
save_into_db = PythonOperator(
  task_id='save_into_db',
    python_callable=store_in_db
)
notify_data_science_team = SlackWebhookOperator(
 task_id='notify_data_science_team',
 http_conn_id='slack_conn',
  webhook_token=slack_token,
 message="Data Science Notification \n"
    .. .. .. 
)
# Step two, declare task dependencies in the workflow
 is_new_data_available >> transform_data
 transform_data >> create_table >> save_into_db
 save_into_db >> notify_data_science_team
 save_into_db >> create_report
# The actual data transformation logic, which is referenced 
# in the “transform_data” task.
def transform_data(*args, **kwargs):
    .. .. ..

在代码清单9.1中,咱们能够看到样例作业流DAG包括多个使命,例如create_table和save_into_db。在Airflow中,使命被完成为操作符(operator)。Airflow供给了许多预界说的和由社区办理的操作符,例如MySqlOperator、SimpleHttpOperator和DockerOperator。

Airflow的预界说操作符协助用户在无需编码的状况下完成使命。您还能够运用PythonOperator来运转自界说的Python函数。一旦作业流DAG构建完结而且一切代码布置到Airflow中,咱们能够运用UI或以下CLI指令来检查作业流的履行状况。以下是一些示例Shell指令:

airflow dags list
airflow tasks list data_process_dag
airflow tasks list data_process_dag --tree

假如您想了解更多关于Airflow的信息,能够检查其架构概述文档和教程(mng.bz/Blpw)。

要害功用

Airflow供给以下要害功用:

  • DAGs:Airflow经过运用DAGs(有向无环图)来笼统杂乱的作业流,作业流DAG是经过Python库来完成的。
  • 编程式作业流办理:Airflow支撑动态创立使命,并答应创立杂乱的动态作业流。
  • 超卓的内置操作符以协助构建主动化:Airflow供给了许多预界说的操作符,能够协助用户在不编写代码的状况下完结使命。
  • 坚实的使命依靠和履行办理:Airflow在每个使命中内置了主动重试战略,并供给了不同类型的传感器来处理运转时的依靠联系,例如检测使命完结、作业流运转状况变化和文件存在等。
  • 可扩展性:Airflow使其传感器、钩子和操作符彻底可扩展,这使得它能够从许多的社区贡献的操作符中受益。经过增加自界说操作符,Airflow也能够轻松集成到不同的体系中。
  • 监控和办理界面:Airflow供给了强壮的用户界面,用户能够快速检查作业流/使命的履行状况和前史。用户还能够从界面上触发和清除使命或作业流运转。
  • 用于出产环境的高质量:Airflow供给了许多有用的东西,用于在出产环境中保护服务,如使命日志搜索、扩展性、警报和RESTful API。

局限性

  • 关于数据科学家来说,运用Airflow需求付出较高的学习本钱:Airflow关于完成不受内置操作符支撑的使命有较高的学习曲线。此外,没有简略的办法来进行作业流的本地测验。

  • 将深度学习原型代码转移到出产环境时存在较高的阻力:在将Airflow应用于深度学习时,数据科学家有必要将他们的本地模型练习代码转化为Airflow DAG。这是额定的作业量,关于数据科学家来说是一种不愉快的体会,尤其是考虑到假如咱们直接从模型练习代码构建作业流DAG的话,能够防止这种状况。

  • 在Kubernetes上操作时存在较高的杂乱性:在Kubernetes上布置和操作Airflow并不直观。假如您期望采用一个在Kubernetes上运转的编列体系,Argo Workflows是更好的挑选。

Argo Workflows

Argo Workflows是一个开源的、基于容器的作业流引擎,用于在Kubernetes上编列并行作业流/使命。Argo Workflows处理了与Airflow相同的问题,但采用了不同的方法,它采用了与Kubernetes本地化的办法。

Argo Workflows与Airflow之间最大的区别在于,Argo Workflows是基于Kubernetes原生构建的。具体而言,Argo Workflows中的作业流和使命是以Kubernetes自界说资源界说(CRD)目标的方法完成的,每个使命(进程)作为一个Kubernetes pod履行。请拜见图9.6,了解高级体系概述。

《设计深度学习系统》第九章:工作流编排

在图9.6中,数据科学家Vena首要将作业流和其进程/使命界说为Kubernetes CRD目标,一般以YAML文件的方法出现。然后,她将作业流提交给Argo Workflows,其操控器在Kubernetes集群内创立CRD目标。接下来,Kubernetes动态发动Pod来依照作业流序列运转进程/使命。 您或许还留意到,每个进程的履行都经过容器和Pod彻底阻隔;每个进程运用文件来表明其输入和输出值。Argo Workflows会主动将依靠文件挂载到进程的容器中。

由Kubernetes Pod创立的使命阻隔是Argo Workflows的重要优势。一起,简略性也是人们挑选Argo Workflows的另一个原因。假如您了解Kubernetes,Argo的安装和毛病扫除都是直接的。咱们能够运用Argo Workflows指令或标准的Kubernetes CLI指令来调试体系。

典型用例

为了更好地了解,让咱们看一个Argo Workflows的示例。在本节中,咱们运用Argo Workflows来主动化前面在Airflow部分中看到的相同的数据处理作业。作业流包括首要检查新数据,对数据进行转化,将其保存到数据库中的新表中,然后经过Slack告诉数据科学家团队。请拜见以下代码示例,其中界说了Argo Workflows的作业流。

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: data-processing-
spec:
entrypoint: argo-steps-workflow-example
templates:
 - name: argo-steps-workflow-example
  Steps:
   - - name: check-new-data
     template: data-checker
   - - name: transform-data
     template: data-converter
     arguments:
            artifacts:
              - name: data-paths
                from: "{{steps.check-new-data.outputs.
                 artifacts.new-data-paths}}"
     - - name:save-into-db
         template: postgres-operator
     - - name: notify-data-science-team
       template: slack-messenger
 - name: data-checker
  container:
   image: docker/data-checker:latest
   command: [scan, /datastore/ds/]
  outputs:
   artifacts:
    - name: new-data-paths
     path: /tmp/data_paths.txt
 - name: data-converter
  inputs:
   artifacts:
    - name: data_paths
         path: /tmp/raw_data/data_paths.txt
   container:
      image: docker/data-checker:latest
      command: [data_converter, /tmp/raw_data/data_paths.txt]
- name: save-into-db
  .. .. ..
- name: notify-data-science-team
  .. .. ..

在Argo Workflows中,最基本的概念是作业流(workflow)和模板(template)。作业流目标表明作业流的单个实例,包括作业流的界说和履行状况。咱们应该将作业流视为一个“活动”的目标。模板能够被视为函数,它们界说要履行的指令。entrypoint字段界说了主函数,也便是将首要履行的模板。

在代码清单9.2中,咱们看到一个包括四个进程的次序作业流:check-new-data -> transform_data -> save-into-db -> notify-data-science-team。每个进程能够引证一个模板,并经过artifacts(文件)传递参数。例如,check-new-data引证了data-checker模板,该模板界说了用于检查是否有新数据的Docker镜像。data-checker模板还声明了进程输出——新抵达的数据文件路径将保存到/tmp/data_paths.txt作为输出值。

接下来,进程transform_data将check-new-data的输出绑定到data-converter模板的输入。这便是变量在进程和模板之间传递的方法。一旦您提交了作业流(例如,argo submit -n argo sample_workflow.yaml),您能够运用Argo Workflows的UI或以下指令来检查作业流运转的详细信息:

# list all the workflows
argo list -n argo
# get details of a workflow run
argo get -n argo {workflow_name}

除了运用argo指令,咱们还能够运用Kubernetes CLI指令来检查作业流的履行状况,由于Argo Workflows是在Kubernetes上原生运转的;以下是一个示例:

# list all argo customer resource definitions
kubectl get crd -n argo
# list all workflows
kubectl get workflows -n argo
# check specific workflow
kubectl describe workflow/{workflow_name} -n argo

要了解更多关于Argo Workflows的信息,您能够检查Argo Workflows用户攻略(mng.bz/WAG0)和Argo Workflows架构图(argoproj.github.io/argo-workfl…)。

代码Docker化:快捷的出产布置 Argo Workflows本质上是一个Kubernetes Pod(Docker镜像)调度体系。虽然它要求将代码编写为一系列的Docker镜像,但它在编列体系内部供给了很大的灵敏性和阻隔性。由于代码以Docker方法存在,它能够在任何作业节点上履行,而无需忧虑装备作业节点环境。

Argo Workflows的另一个优势是其低本钱的出产布置。当您在Docker中本地测验代码时,Docker镜像(原型代码)能够直接在Argo Workflows中运用。与Airflow不同,Argo Workflows几乎不需求将原型代码转化为出产作业流的作业。

要害特色

Argo Workflows具有以下要害特色:

  • 低本钱的安装和保护 – Argo Workflows原生运转在Kubernetes上,因而您能够直接运用Kubernetes进程来处理任何问题,无需学习其他东西。此外,它的安装十分简略;经过几个kubectl指令,您就能够在Kubernetes环境中运转Argo Workflows。
  • 强壮的作业流履行 – Kubernetes Pod为Argo Workflows的使命履行供给了杰出的阻隔性。Argo Workflows还支撑守时作业流和使命重试。
  • 模板和组合性 – Argo Workflows的模板相似于函数。在构建作业流时,Argo Workflows支撑组合不同的模板(进程函数)。这种组合性鼓舞团队之间同享通用作业,然后极大地进步了出产力。
  • 完善的用户界面 – Argo Workflows供给快捷的用户界面,用于办理整个作业流的生命周期,例如提交/停止作业流、列出一切作业流和检查作业流界说。
  • 高度灵敏和适用 – Argo Workflows界说了用于办理体系和增加新功用(插件)的REST API,并将作业流使命界说为Docker镜像。这些特性使得Argo Workflows具有高度的可定制性,并在许多范畴广泛应用,如机器学习、ETL、批处理/数据处理和继续集成/继续交给/继续布置(CI/CD)。
  • 适用于出产环境 – Argo Workflows专为严肃的出产环境而规划。Kubeflow Pipeline和Argo CD是出产化Argo Workflows的绝佳示例。

局限性

运用Argo Workflows的深度学习体系的缺陷如下:

  • 每个人都需求编写和保护YAML文件 – Argo Workflows要求将作业流界说为一个Kubernetes CRD(自界说资源界说)的YAML文件。关于单个项目而言,矮小的YAML文件仍是能够办理的,可是一旦作业流数量增多而且作业流逻辑变得愈加杂乱,YAML文件或许会变得冗长和令人困惑。Argo Workflows供给了模板来简化作业流界说,但除非您习惯于运用Kubernetes的YAML装备,不然依然不太直观。
  • 有必要成为Kubernetes的专家 – 假如您是Kubernetes的专家,那么运用Argo Workflows或许会感觉自然而然。可是关于新手用户来说,或许需求花费相当多的时刻学习Kubernetes的概念和实践。
  • 使命履行延迟 – 在Argo Workflows中,关于每个新使命,Argo都会发动一个新的Kubernetes Pod来履行它。Pod的发动或许会导致每个使命的履行时刻增加数秒或数分钟,这约束了Argo在支撑对时刻灵敏的作业流时的表现。例如,Argo Workflows不适合具有毫秒级服务等级协议(SLA)的实时模型猜测作业流,由于该作业流会处理毫秒级的模型猜测恳求。

Metaflow

Metaflow是一个注重MLOps的用户友好的Python库。它开端由Netflix开发,并于2019年开源。Metaflow的特色在于它遵从以人为中心的规划准则,不只用于主动化作业流程,还旨在减少在深度学习项目开发中耗费的人力时刻(操作本钱)。

在9.1.3节中,咱们指出了从原型代码到出产作业流的转化在机器学习开发中引发了许多冲突。数据科学家有必要为每个模型开发迭代构建和测验一个新版别的作业流程。为了弥合原型和出产之间的距离,Metaflow进行了两个改善:首要,简化了作业流程的构建;其次,一致了本地环境和出产环境中的作业流程履行体会(见图9.7)。

《设计深度学习系统》第九章:工作流编排

在图9.7中,咱们能够看到Metaflow将原型和出产环境都视为一流的履行环境。由于Metaflow库供给了一组一致的API来笼统实践的根底架构,不管在哪个环境中运转,作业流程都能够以相同的方法履行。例如,作业流能够经过本地调度程序和出产调度程序运转,而无需进行任何更改。本地调度程序在本地履行作业流程,而出产调度程序则集成到其他出产编列体系中,如AWS Step Functions或Argo Workflows。

Metaflow答应用户运用Python注释来对Python代码进行标示,以界说作业流程。Metaflow库会依据Python注释主动创立/打包作业流程。有了Metaflow的Python注释,Vena能够在不改变她的原型代码的状况下构建作业流程。 除了无缝的作业流程创立和测验,Metaflow还供给了其他有用的功用,关于模型的可重复性十分重要,例如作业流程/进程的版别操控和进程的输入/输出保存。假如想了解更多关于Metaflow的信息,能够查阅Metaflow的官方网站(docs.metaflow.org/)以及Ville Tuulos所著的Metaflow书本《Effective Data Science Infrastructure》(Manning出版社,2022年;www.manning.com/books/effec…)。

典型用户事例

以下是运用Metaflow来主动化之前在9.3.1和9.3.2节中看到的相同数据处理作业的伪代码示例:

# define workflow DAG in a python class
class DataProcessWorkflow(FlowSpec):
 # define "data source" as an input parameter for the workflow
 data_source = Parameter(
      "datasource_path", help="the data storage location for data process"
  , required=True
 )
 @step
 def start(self):
    # The parameter “self.data_source” are available in all steps. 
    self.newdata_path = dataUtil.fetch_new_data(self.data_source)
  self.next(self.transform_data)
 @step
 def transform_data(self):
      self.new_data = dataUtil.convert(self.newdata_path)
      # fan out to two parallel branches after data transfer.   
      self.next(self.save_to_db, self.notify_data_science_team)
 @step
 def save_to_db(self):
    dataUtil.store_data(self.new_data)
    self.next(self.join)
 @step
 def notify_data_science_team(self):
     slackUtil.send_notification(messageUtil.build_message(self.new_data))
   self.next(self.join)
 # join the two parallel branches steps:
 # notify_data_science_team and save_to_db
  @step
 def join(self, inputs):
  self.next(self.end)
 @step
 def end(self, inputs):
  # end the flow.
  pass
if __name__ == "__main__":
 DataProcessWorkflow()

在代码清单9.3中,咱们能够看到Metaflow采用了一种新颖的办法来构建作业流,运用代码注解来符号函数,并运用self.next函数来衔接进程,咱们能够轻松地从咱们的原型代码构建一个作业流DAG(图9.8)。

《设计深度学习系统》第九章:工作流编排

这儿的一个长处是咱们不需求在单独的体系中界说作业流DAG,并将代码从头打包成不同的格局,比方Docker镜像。Metaflow作业流嵌入在咱们的代码中。作业流开发和原型代码开发产生在同一个当地,而且能够从整个机器学习开发周期的开端到完毕一同进行测验。 一旦代码预备好了,咱们能够在本地验证和运转作业流。请参阅以下示例指令:

# display workflow DAG
python data_process_workflow.py show
# run the workflow locally
python data_process_workflow.py run

一旦咱们完结了本地开发和测验,就能够经过以下两个指令将作业流推送到出产环境:

# push the workflow from local to AWS step functions
python data_process_workflow.py --with retry step-functions create
# push the workflow from local to Argo workflows
python data_process_workflow.py --with retry argo-workflows create

这些指令将咱们在代码清单9.3中界说的数据处理作业流导出到AWS Step Functions和Argo Workflows。然后,您能够在AWS Step Functions UI或Argo Workflows UI中经过称号搜索该作业流,并检查导出的作业流。

留意: Metaflow在本地和出产环境之间供给一致的开发体会。由于Metaflow供给了一致的API,咱们在本地和出产环境中测验代码和作业流时具有无缝的体会。不管运用的是Metaflow本地调度程序、Argo Workflows仍是AWS Step Functions作为后端作业流编列体系,Metaflow在作业流开发方面的用户体会坚持一致!

首要功用

Metaflow供给以下首要功用:

  • 将代码结构化为作业流程—Metaflow答应用户经过对Python代码进行注释来创立作业流程,大大简化了作业流程的构建。
  • 可复现性—Metaflow保存了履行每个作业流程进程所需的数据、代码和外部依靠项的不行变快照。Metaflow还记录了每个作业流程履行的元数据。
  • 版别操控—Metaflow经过对作业流程中的一切代码和数据进行哈希处理来处理ML项意图版别操控需求。
  • 强壮的作业流程履行—元数据供给了作业流程等级和进程等级的依靠办理机制,运用@conda装饰器完成。它还供给了使命重试功用。
  • 针对机器学习的易用性规划—Metaflow将原型和出产视为平等重要。它供给了一组一致的API来笼统根底设施,因而相同的代码能够在原型环境和出产环境中运转而无需进行任何更改。
  • 无缝可扩展性—Metaflow集成了Kubernetes和AWS Batch,运用户能够轻松界说所需的核算资源,并能够在任意数量的实例上并行履行作业流程进程。例如,经过将相似@batch(cpu=1, memory=500)的注释应用于进程函数,Metaflow将与AWS Batch合作分配所需的资源来核算此进程。

局限性

在深度学习体系中运用Metaflow的缺陷如下:

  • 不支撑条件分支—Metaflow的进程注释不支撑条件分支(只有当条件满意时才履行某个进程)。这不是一个严重问题,但这是一个很好的功用。
  • 没有作业调度程序—Metaflow自身没有作业调度程序,因而无法运用cron作业流。这不是一个大问题,由于Metaflow能够与其他支撑作业调度的编列体系集成,如AWS Step Functions和Argo Workflows。
  • 与AWS严密耦合—Metaflow的最重要功用与AWS严密耦合,例如Amazon S3和AWS Batch。走运的是,Metaflow是一个开源项目,因而能够将其扩展到非AWS的替代计划中。

何时运用

假如你正在寻觅一个用于非机器学习项目主动化作业流履行的编列体系,Airflow和Argo Workflows都是很好的挑选。它们都有超卓的社区支撑,并在IT职业广泛运用。假如你的体系运转在Kubernetes上,而且团队对运用Docker感到舒适,那么Argo Workflows是一个很好的挑选;不然,Airflow也不会让你失望。

假如你正在寻觅一个用于简化机器学习项目开发的体系,Metaflow是强烈推荐的挑选。Metaflow不只是一个编列东西,更是一个专心于节约数据科学家在机器学习开发周期中时刻的MLOps东西。由于Metaflow笼统了机器学习项意图后端根底设施部分,数据科学家能够专心于模型开发,而不必忧虑出产环境的转化和布置。

总结

  • 作业流程是某个更大使命的一系列操作。作业流程能够被视为进程的有向无环图(DAG)。进程是最小的可恢复核算单元,描绘了要履行的操作;一个进程要么成功完结,要么彻底失利。DAG指定了进程之间的依靠联系和履行次序。

  • 作业流编列是依据作业流程DAG中界说的次序履行作业流程进程。

  • 采用作业流程鼓舞作业同享、团队协作和主动化。

  • 在应用作业流程于深度学习项目时,首要应战是下降作业流程构建本钱,简化作业流程的测验和调试。

  • 构建/评价作业流程编列体系的六个推荐规划准则是:重要性、易用性、可扩展性、使命阻隔性、可扩展性和以人为中心性。

  • 挑选非机器学习项意图编列体系时,Airflow和Argo Workflows都是很好的挑选。假如项目运转在Kubernetes和Docker上,Argo Workflows是更好的挑选。

  • 挑选机器学习项意图编列体系时,Metaflow目前是最佳挑选。