
# 创建Workflow服务部署节点
#### 功能介绍
通过对ModelArts服务管理能力的封装，实现Workflow新增服务和更新服务的能力。主要应用场景如下：
- 将模型部署为一个Web Service。
- 更新已有服务，支持灰度更新等能力。
 
#### 属性总览
您可以使用**ServiceStep** 来构建服务部署节点，**ServiceStep**结构如下
表1**ServiceStep** 
| 属性           | 描述                                                                                       | 是否必填 | 数据类型                            |
|:---|:---|:---|:---|
| name         | 服务部署节点的名称，命名规范(只能包含英文字母、数字、下划线（_）、中划线（-），并且只能以英文字母开头，长度限制为64字符)，一个Workflow里的两个step名称不能重复 | 是    | str                             |
| inputs       | 服务部署节点的输入列表                                                                              | 否    | ServiceInput或者ServiceInput的列表   |
| outputs      | 服务部署节点的输出列表                                                                              | 是    | ServiceOutput或者ServiceOutput的列表 |
| title        | title信息，主要用于前端的名称展示                                                                      | 否    | str                             |
| description  | 服务部署节点的描述信息                                                                              | 否    | str                             |
| policy       | 节点执行的policy                                                                              | 否    | StepPolicy                      |
| depend_steps | 依赖的节点列表                                                                                  | 否    | Step或者Step的列表                   |
   
表2**ServiceInput** 
| 属性   | 描述                                                                                 | 是否必填 | 数据类型                                                                          |
|:---|:---|:---|:---|
| name | 服务部署节点的输入名称，命名规范(只能包含英文字母、数字、下划线（_）、中划线（-），并且只能以英文字母开头，长度限制为64字符)。同一个Step的输入名称不能重复 | 是    | str                                                                           |
| data | 服务部署节点的输入数据对象                                                                      | 是    | 模型列表或服务相关对象，当前仅支持ServiceInputPlaceholder，ServiceData，ServiceUpdatePlaceholder |
   
表3**ServiceOutput** 
| 属性             | 描述                                                                                 | 是否必填 | 数据类型          |
|:---|:---|:---|:---|
| name           | 服务部署节点的输出名称，命名规范(只能包含英文字母、数字、下划线（_）、中划线（-），并且只能以英文字母开头，长度限制为64字符)。同一个Step的输出名称不能重复 | 是    | str           |
| service_config | 服务部署相关配置信息                                                                         | 是    | ServiceConfig |
   
**表4 ServiceConfig**
| 属性                    | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | 是否必填 | 数据类型                 |
|:---|:---|:---|:---|
| infer_type            | 推理方式：取值可为real-time/batch/edge。默认为real-time。 - real-time代表在线服务，将模型部署为一个Web Service。  - batch为批量服务，批量服务可对批量数据进行推理，完成数据处理后自动停止。  - edge表示边缘服务，通过华为云智能边缘平台，在边缘节点将模型部署为一个Web Service，需提前在IEF（智能边缘服务）创建好节点。   | 是    | str                  |
| service_name          | 服务名称，支持1-64位可见字符（含中文），名称可以包含字母、中文、数字、中划线、下划线。 说明： 该字段不填时默认为自动生成的服务名称。                                                                                                                                                                                                                                                                                                                                                                                                                                        | 否    | str、Placeholder      |
| description           | 服务备注，默认为空，不超过100个字符。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | 否    | str                  |
| vpc_id                | 在线服务实例部署的虚拟私有云ID，默认为空，此时ModelArts会为每个用户分配一个专属的VPC，用户之间隔离。如需要在服务实例中访问名下VPC内的其他服务组件，则可配置此参数为对应VPC的ID。VPC一旦配置，不支持修改。当vpc_id与cluster_id一同配置时，只有专属资源池参数生效。                                                                                                                                                                                                                                                                                                                                                                                                                                                   | 否    | str                  |
| subnet_network_id     | 子网的网络ID，默认为空，当配置了vpc_id则此参数必填。需填写[VPC管理控制台](https://console.huaweicloud.com)子网详情中显示的"网络ID"。通过子网可提供与其他网络隔离的、可以独享的网络资源。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | 否    | str                  |
| security_group_id     | 安全组，默认为空，当配置了vpc_id则此参数必填。安全组起着虚拟防火墙的作用，为服务实例提供安全的网络访问控制策略。安全组须包含至少一条入方向规则，对协议为TCP、源地址为0.0.0.0/0、端口为8080的请求放行。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | 否    | str                  |
| cluster_id            | 专属资源池ID，默认为空，不使用专属资源池。使用专属资源池部署服务时需确保集群状态正常；配置此参数后，则使用集群的网络配置，vpc_id参数不生效；与下方real-time config中的cluster_id同时配置时，优先使用real-time config中的cluster_id参数。                                                                                                                                                                                                                                                                                                                                                                                                                                                      | 否    | str                  |
| additional_properties | 附加的相关配置信息。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | 否    | dict                 |
| apps                  | 服务部署支持APP认证。支持填入多个app name。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | 否    | str、Placeholder、list |
| envs                  | 环境变量                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | 否    | dict                 |
   
示例：
```
example = ServiceConfig()
# 主要在服务部署节点的输出中使用
```
如果您没有特殊需求，可直接使用内置的默认值。
#### 使用案例
主要包含三种场景的用例：
- 新增在线服务
- 更新在线服务
- 服务部署输出推理地址
 
#### 新增在线服务
```
import modelarts.workflow as wf
# 通过ServiceStep来定义一个服务部署节点，输入指定的模型进行服务部署
# 定义模型名称参数
model_name = wf.Placeholder(name="placeholder_name", placeholder_type=wf.PlaceholderType.STR)
service_step = wf.steps.ServiceStep(
    name="service_step", # 服务部署节点的名称，命名规范(只能包含英文字母、数字、下划线（_）、中划线（-），并且只能以英文字母开头，长度限制为64字符)，一个Workflow里的两个step名称不能重复
    title="新增服务",  # 标题信息
    inputs=wf.steps.ServiceInput(name="si_service_ph", data=wf.data.ServiceInputPlaceholder(name="si_placeholder1", 
                                                                                  # 模型名称的限制/约束,在运行态只能选择该模型名称；一般与模型注册节点中的model_name使用同一个参数对象
                                                                                  model_name=model_name)),# ServiceStep的输入列表
    outputs=wf.steps.ServiceOutput(name="service_output") # ServiceStep的输出
)
workflow = wf.Workflow(
    name="service-step-demo",
    desc="this is a demo workflow",
    steps=[service_step]
)
```
#### 更新在线服务
使用场景：使用新版本的模型对已有的服务进行更新，需要保证新版本的模型与已部署服务的模型名称一致。
```
import modelarts.workflow as wf
# 通过ServiceStep来定义一个服务部署节点，输入指定的模型对已部署的服务进行更新
# 定义模型名称参数
model_name = wf.Placeholder(name="placeholder_name", placeholder_type=wf.PlaceholderType.STR)
# 定义服务对象
service = wf.data.ServiceUpdatePlaceholder(name="placeholder_name")
service_step  = wf.steps.ServiceStep(
    name="service_step", # 服务部署节点的名称，命名规范(只能包含英文字母、数字、下划线（_）、中划线（-），并且只能以英文字母开头，长度限制为64字符)，一个Workflow里的两个step名称不能重复
    title="服务更新", # 标题信息
    inputs=[wf.steps.ServiceInput(name="si2", data=wf.data.ServiceInputPlaceholder(name="si_placeholder2", 
                                                                                  # 模型名称的限制/约束,在运行态只能选择该模型名称
                                                                                  model_name=model_name)),
           wf.steps.ServiceInput(name="si_service_data", data=service) # 已部署的服务在运行时配置；data也可使用wf.data.ServiceData(service_id="fake_service")表示
    ], # ServiceStep的输入列表
    outputs=wf.steps.ServiceOutput(name="service_output") # ServiceStep的输出
)
workflow = wf.Workflow(
    name="service-step-demo",
    desc="this is a demo workflow",
    steps=[service_step]
)
```
#### 服务部署输出推理地址
服务部署节点支持输出推理地址，通过**get_output_variable("access_address")**方法获取输出值，并在后续节点中使用。
- 针对部署在公共资源池的服务，可以通过**access_address**属性从输出中获取注册在公网的推理地址。
- 针对部署在专属资源池的服务，除了可以获取注册在公网的推理地址，还能通过**cluster_inner_access_address** 属性从输出中获取内部使用的推理地址，并且该地址只能在其他推理服务中进行访问。
  ```
  import modelarts.workflow as wf
  # 定义模型名称参数
  sub_model_name = wf.Placeholder(name="si_placeholder1", placeholder_type=wf.PlaceholderType.STR)
  sub_service_step = wf.steps.ServiceStep(
      name="sub_service_step", # 服务部署节点的名称，命名规范(只能包含英文字母、数字、下划线（_）、中划线（-），并且只能以英文字母开头，长度限制为64字符)，一个Workflow里的两个step名称不能重复
      title="子服务",  # 标题信息
      inputs=wf.steps.ServiceInput(
          name="si_service_ph",
          data=wf.data.ServiceInputPlaceholder(name="si_placeholder1", model_name=sub_model_name)
      ),# ServiceStep的输入列表
      outputs=wf.steps.ServiceOutput(name="service_output") # ServiceStep的输出
  )
  main_model_name = wf.Placeholder(name="si_placeholder2", placeholder_type=wf.PlaceholderType.STR)
  # 获取子服务输出的推理地址，并通过envs传递给主服务
  main_service_config = wf.steps.ServiceConfig(
      infer_type="real-time", 
      envs={"infer_address": sub_service_step.outputs["service_output"].get_output_variable("access_address")} # 获取子服务输出的推理地址，并通过envs传递到主服务中
  )
  main_service_step = wf.steps.ServiceStep(
      name="main_service_step", # 服务部署节点的名称，命名规范(只能包含英文字母、数字、下划线（_）、中划线（-），并且只能以英文字母开头，长度限制为64字符)，一个Workflow里的两个step名称不能重复
      title="主服务",  # 标题信息
      inputs=wf.steps.ServiceInput(
          name="si_service_ph",
          data=wf.data.ServiceInputPlaceholder(name="si_placeholder2", model_name=main_model_name)
      ),# ServiceStep的输入列表
      outputs=wf.steps.ServiceOutput(name="service_output", service_config=main_service_config), # ServiceStep的输出
      depend_steps=sub_service_step
  )
  workflow = wf.Workflow(
      name="service-step-demo",
      desc="this is a demo workflow",
      steps=[sub_service_step, main_service_step]
  )
  ```
  
#### 同步推理服务部署相关信息配置操作
在开发态中（一般指Notebook），节点启动运行后，用户根据日志打印的输入格式配置，如下所示：
![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000001941945558.png "点击放大")
1. 在[ModelArts管理控制台](https://console.huaweicloud.com/modelarts/)，左侧菜单栏选择"开发空间\>Workflow"进入Workflow页面。
2. 在服务部署节点启动之后会等待用户设置相关配置信息，配置完成后直接单击"继续运行"即可。 如果想要跳过手动配置的步骤，直接自动运行部署节点，则按照需要在代码中提前配置ServiceInputConfig或ServiceConfig参数，如：service_config=wf.steps.ServiceConfig(cluster_id="XX")。当不缺少参数时，服务部署节点将会自动启动。
   ![](https://support.huaweicloud.com/usermanual-standard-modelarts/figure/zh-cn_image_0000002042222292.png "点击放大")
   
 
#### 异步推理服务部署相关信息配置操作
1. 在[ModelArts管理控制台](https://console.huaweicloud.com/modelarts/)，左侧菜单栏选择"Workflow"进入Workflow页面。
2. 在服务部署节点启动之后会等待用户设置相关配置信息，选择模型及版本为异步推理模型，设置**服务启动参数** ，配置完成后直接单击**继续运行** 即可。
   
   
![](https://support.huaweicloud.com/usermanual-standard-modelarts/public_sys-resources/note_3.0-zh-cn.png)
其中**服务启动参数** 与您选择的异步推理模型相关，选择了需要的模型及版本后，系统会自动匹配相应的**服务启动参数**。
