
# 开发Workflow的核心概念介绍
#### Workflow
Workflow是一个有向无环图（Directed Acyclic Graph，DAG），由节点和节点之间的关系描述组成。
图1Workflow介绍   
![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000001969104533.png "点击放大")
节点与节点之间的依赖关系由单箭头的线段来表示，依赖关系决定了节点的执行顺序，示例中的工作流在启动后将从左往右顺序执行。DAG也支持多分支结构，用户可根据实际场景进行灵活设计，在多分支场景下，并行分支的节点支持并行运行，具体请参考[配置多分支节点数据](https://support.huaweicloud.com/usermanual-standard-modelarts/modelarts_workflow_0399.html)章节。
表1Workflow 
| 属性       | 描述                                                           | 是否必填 | 数据类型                     |
|:---|:---|:---|:---|
| name     | 工作流的名称，命名规范(只能包含英文字母、数字、下划线（_）、中划线（-），并且只能以英文字母开头，长度限制为64位字符 | 是    | str                      |
| desc     | 工作流的描述信息                                                     | 是    | str                      |
| steps    | 工作流包含的节点列表                                                   | 是    | list\[Step\]             |
| storages | 统一存储对象列表                                                     | 否    | Storage或者list\[Storage\] |
| policy   | 工作流的配置策略，主要用于部分运行场景                                          | 否    | Policy                   |
   
#### Step
Step是组成Workflow的最小单元，体现在DAG中就是一个一个的节点，不同的Step类型承载了不同的服务能力，主要构成如下。
表2Step 
| 属性           | 描述                                                         | 是否必填 | 数据类型                                   |
|:---|:---|:---|:---|
| name         | 节点的名称，命名规范(只能包含英文字母、数字、下划线（_）、中划线（-），并且只能以英文字母开头，长度限制为64字符 | 是    | str                                    |
| title        | 节点的标题信息，主要用于在DAG中的展示，如果该字段未填写，则默认使用name进行展示                | 否    | str                                    |
| step_type    | 节点的类型，决定了节点的功能                                             | 是    | enum                                   |
| inputs       | 节点的输入列表                                                    | 否    | AbstractInput或者list\[AbstractInput\]   |
| outputs      | 节点的输出列表                                                    | 否    | AbstractOutput或者list\[AbstractOutput\] |
| properties   | 节点的属性信息                                                    | 否    | dict                                   |
| policy       | 节点的执行策略，主要包含节点调度运行的时间间隔、节点执行的超时时间、以及节点执行是否跳过的相关配置          | 否    | StepPolicy                             |
| depend_steps | 依赖节点的列表，该字段决定了DAG的结构，也决定了节点执行的顺序                           | 否    | Step或者list\[Step\]                     |
   
表3StepPolicy 
| 属性                    | 描述                      | 是否必填 | 数据类型                   |
|:---|:---|:---|:---|
| poll_interval_seconds | 节点调度时间周期，默认为1秒          | 是    | str                    |
| max_execution_minutes | 节点运行超时时间，默认为10080分钟，即7天 | 是    | str                    |
| skip_conditions       | 节点是否跳过的条件列表             | 否    | Condition或者Condition列表 |
   
Step是节点的超类，主要用于概念上的承载，用户不直接使用。根据功能的不同，构建了不同类型的节点，主要包括**CreateDatasetStep** 、**LabelingStep** 、**DatasetImportStep** 、**ReleaseDatasetStep** 、**JobStep** 、**ModelStep** 、**ServiceStep** 、**ConditionStep** 等，详情请见[创建Workflow节点](https://support.huaweicloud.com/usermanual-standard-modelarts/modelarts_workflow_0363.html)。
#### Data
数据对象用于节点的输入，主要可分为以下三种类型：
- 真实的数据对象，在工作流构建时直接指定：
  - Dataset：用于定义已有的数据集，常用于数据标注，模型训练等场景
  
  - LabelTask: 用于定义已有的标注任务，常用于数据标注，数据集版本发布等场景
  
  - OBSPath：用于定义指定的OBS路径，常用于模型训练，数据集导入，模型导入等场景
  
  - ServiceData：用于定义一个已有的服务，只用于服务更新的场景
  
  - SWRImage：用于定义已有的SWR路径，常用于模型注册场景
  
  - GalleryModel：用于定义从订阅的模型，常用于模型注册场景
   

- 占位符式的数据对象，在工作流运行时指定：
  - DatasetPlaceholder：用于定义在运行时需要确定的数据集，对应Dataset对象，常用于数据标注，模型训练等场景
  
  - LabelTaskPlaceholder：用于定义在运行时需要确定的标注任务，对应LabelTask对象，常用于数据标注，数据集版本发布等场景
  
  - OBSPlaceholder：用于定义在运行时需要确定的OBS路径，对应OBSPath对象，常用于模型训练，数据集导入，模型导入等场景
  
  - ServiceUpdatePlaceholder：用于定义在运行时需要确定的已有服务，对应ServiceData对象，只用于服务更新的场景
  
  - SWRImagePlaceholder：用于定义在运行时需要确定的SWR路径，对应SWRImage对象，常用于模型注册场景
  
  - ServiceInputPlaceholder：用于定义在运行时需要确定服务部署所需的模型相关信息，只用于服务部署及服务更新场景
  
  - DataSelector：支持多种数据类型的选择，当前仅支持在JobStep节点中使用（仅支持选择OBS或者数据集）
   
- 数据选择对象： DataConsumptionSelector：用于在多个依赖节点的输出中选择一个有效输出作为数据输入，常用于存在条件分支的场景中（在构建工作流时未能确定数据输入来源为哪个依赖节点的输出，需根据依赖节点的实际执行情况进行自动选择）
  
表4**Dataset** 
| 属性           | 描述      | 是否必填 | 数据类型 |
|:---|:---|:---|:---|
| dataset_name | 数据集名称   | 是    | str  |
| version_name | 数据集版本名称 | 否    | str  |
   
示例：
```
example = Dataset(dataset_name = "**", version_name = "**")
 # 通过ModelArts的数据集，获取对应的数据集名称及相应的版本名称。
```
![](https://support.huaweicloud.com/usermanual-standard-modelarts/public_sys-resources/note_3.0-zh-cn.png)
当Dataset对象作为节点的输入时，需根据业务需要自行决定是否填写version_name字段（比如LabelingStep、ReleaseDatasetStep不需要填写，JobStep必须填写）。
表5**LabelTask** 
| 属性           | 描述     | 是否必填 | 数据类型 |
|:---|:---|:---|:---|
| dataset_name | 数据集名称  | 是    | str  |
| task_name    | 标注任务名称 | 是    | str  |
   
示例：
```
example = LabelTask(dataset_name = "**", task_name = "**")
 # 通过ModelArts的新版数据集，获取对应的数据集名称及相应的标注任务名称
```
表6**OBSPath** 
| 属性       | 描述    | 是否必填 | 数据类型        |
|:---|:---|:---|:---|
| obs_path | OBS路径 | 是    | str，Storage |
   
示例：
```
example = OBSPath(obs_path = "**")
# 通过对象存储服务，获取已存在的OBS路径值
```
表7**ServiceData** 
| 属性         | 描述    | 是否必填 | 数据类型 |
|:---|:---|:---|:---|
| service_id | 服务的ID | 是    | str  |
   
示例：
```
example = ServiceData(service_id = "**")
# 通过ModelArts的在线服务，获取对应服务的服务ID，描述指定的在线服务。用于服务更新的场景。
```
表8**SWRImage** 
| 属性       | 描述         | 是否必填 | 数据类型 |
|:---|:---|:---|:---|
| swr_path | 容器镜像的SWR路径 | 是    | str  |
   
示例：
```
example = SWRImage(swr_path = "**")
# 容器镜像地址，用于模型注册节点的输入
```
表9**GalleryModel** 
| 属性              | 描述        | 是否必填 | 数据类型 |
|:---|:---|:---|:---|
| subscription_id | 订阅模型的订阅ID | 是    | str  |
| version_num     | 订阅模型的版本号  | 是    | str  |
   
示例：
```
example = GalleryModel(subscription_id="**", version_num="**")
# 订阅的模型对象，用于模型注册节点的输入
```
表10**DatasetPlaceholder** 
| 属性        | 描述                        | 是否必填 | 数据类型         |
|:---|:---|:---|:---|
| name      | 名称                        | 是    | str          |
| data_type | 数据类型                      | 否    | DataTypeEnum |
| delay     | 标志数据对象是否在节点运行时配置，默认为False | 否    | bool         |
| default   | 数据对象的默认值                  | 否    | Dataset      |
   
示例：
```
example = DatasetPlaceholder(name = "**", data_type = DataTypeEnum.IMAGE_CLASSIFICATION)
# 数据集对象的占位符形式，可以通过指定data_type限制数据集的数据类型
```
表11**OBSPlaceholder** 
| 属性          | 描述                               | 是否必填 | 数据类型    |
|:---|:---|:---|:---|
| name        | 名称                               | 是    | str     |
| object_type | 表示OBS对象类型，仅支持"file"或者"directory" | 是    | str     |
| delay       | 标志数据对象是否在节点运行时配置，默认为False        | 否    | bool    |
| default     | 数据对象的默认值                         | 否    | OBSPath |
   
示例：
```
example = OBSPlaceholder(name = "**", object_type = "directory" )
# OBS对象的占位符形式，object_type只支持两种类型， "file" 以及 "directory"
```
表12**LabelTaskPlaceholder** 
| 属性        | 描述                        | 是否必填 | 数据类型              |
|:---|:---|:---|:---|
| name      | 名称                        | 是    | str               |
| task_type | 表示标注任务的类型                 | 否    | LabelTaskTypeEnum |
| delay     | 标志数据对象是否在节点运行时配置，默认为False | 否    | bool              |
   
示例：
```
example = LabelTaskPlaceholder(name = "**")
# LabelTask对象的占位符形式
```
表13**ServiceUpdatePlaceholder** 
| 属性    | 描述                        | 是否必填 | 数据类型 |
|:---|:---|:---|:---|
| name  | 名称                        | 是    | str  |
| delay | 标志数据对象是否在节点运行时配置，默认为False | 否    | bool |
   
示例：
```
example = ServiceUpdatePlaceholder(name = "**")
# ServiceData对象的占位符形式，用于服务更新节点的输入
```
表14**SWRImagePlaceholde** **r** 
| 属性    | 描述                        | 是否必填 | 数据类型 |
|:---|:---|:---|:---|
| name  | 名称                        | 是    | str  |
| delay | 标志数据对象是否在节点运行时配置，默认为False | 否    | bool |
   
示例：
```
example = SWRImagePlaceholder(name = "**" )
# SWRImage对象的占位符形式，用于模型注册节点的输入
```
表15**ServiceInputPlaceholder** 
| 属性            | 描述                         | 是否必填 | 数据类型             |
|:---|:---|:---|:---|
| name          | 名称                         | 是    | str              |
| model_name    | 模型名称                       | 是    | str或者Placeholder |
| model_version | 模型版本                       | 否    | str              |
| envs          | 环境变量                       | 否    | dict             |
| delay         | 服务部署相关信息是否在节点运行时配置，默认为True | 否    | bool             |
   
示例：
```
example = ServiceInputPlaceholder(name = "**" , model_name = "model_name")
# 用于服务部署或者服务更新节点的输入
```
表16**DataSelector** 
| 属性             | 描述                         | 是否必填 | 数据类型 |
|:---|:---|:---|:---|
| name           | 名称                         | 是    | str  |
| data_type_list | 支持的数据类型列表，当前仅支持obs、dataset | 是    | list |
| delay          | 标志数据对象是否在节点运行时配置，默认为False  | 否    | bool |
   
示例：
```
example = DataSelector(name = "**" ,data_type_list=["obs", "dataset"])
# 用于作业类型节点的输入
```
表17**DataConsumptionSelector** 
| 属性        | 描述            | 是否必填 | 数据类型 |
|:---|:---|:---|:---|
| data_list | 依赖节点的输出数据对象列表 | 是    | list |
   
示例：
```
example = DataConsumptionSelector(data_list=[step1.outputs["step1_output_name"].as_input(), step2.outputs["step2_output_name"].as_input()])
# 从step1以及step2中选择有效输出作为输入，当step1跳过无输出，step2执行有输出时，将step2的有效输出作为输入（需保证data_list中同时只有一个有效输出）
```
