管理组件和管道的输入和输出

本文内容:

  • 组件和管道中的输入和输出概述
  • 如何将组件输入/输出提升为管道输入/输出
  • 如何定义可选输入
  • 如何自定义输出路径
  • 如何下载输出
  • 如何将输出注册为命名资产

输入和输出概述

Azure 机器学习管道支持组件级别和管道级别的输入和输出。

在组件级别,输入和输出可定义组件的接口。 一个组件的输出可用作同一父级管道中另一个组件的输入,从而允许在组件之间传递数据或模型。 这种互连形成一个图形,说明了管道中的数据流。

在管道级别,输入和输出对于提交具有不同数据输入或控制训练逻辑的参数的管道作业非常有用(例如 learning_rate)。 在通过 REST 终结点调用管道时,它们会特别有用。 通过这些输入和输出,可以通过 REST 终结点将不同的值分配给管道输入或访问管道作业的输出。 要了解详细信息,请参阅为批处理终结点创建作业和输入数据。

输入和输出的类型

组件或管道的输出支持以下类型

使用数据或模型输出实质上是将输出序列化,并将其作为文件保存在存储位置。 在后续步骤中,可以装载、下载此存储位置或将其上传到计算目标文件系统,以便下一步能够在作业执行期间访问文件。

此过程需要组件的源代码将所需的输出对象(通常存储在内存中)序列化到文件中。 例如,可以将 pandas 数据帧序列化为 CSV 文件。 请注意,Azure 机器学习没有为对象序列化定义任何标准化方法。 用户可以灵活地选择将对象序列化到文件中的首选方法。 接着,在下游组件中,可以独立反序列化和读取这些文件。 下面是一些参考示例:

  • 在 nyc_taxi_data_regression 示例中,prep 组件具有 uri_folder 类型输出。 在组件源代码中,它会从输入文件夹读取 csv 文件,处理文件并将处理过的 CSV 文件写入输出文件夹。
  • 在 nyc_taxi_data_regression 示例中,train 组件具有 mlflow_model 类型输出。 在组件源代码中,它使用 mlflow.sklearn.save_model 方法保存训练的模型。

除了上述数据或模型类型之外,管道或组件输入也可以是以下基元类型

  • string
  • number
  • integer
  • boolean

在 nyc_taxi_data_regression 示例中,train 组件具有名为 test_split_rationumber 输入

注意

不支持基元类型输出。

数据输入/输出的路径和模式

对于数据资产输入/输出,必须指定指向数据位置的 path 参数。 下表显示了 Azure 机器学习管道支持的不同数据位置,并且还显示了路径参数示例:

位置 示例 输入 输出
本地计算机上的路径 ./home/username/data/my_data
公共 http (s) 服务器上的路径 https://raw.githubusercontent.com/pandas-dev/pandas/main/doc/data/titanic.csv
Azure 存储上的路径 wasbs://<container_name>@<account_name>.blob.core.chinacloudapi.cn/<path>
abfss://<file_system>@<account_name>.dfs.core.chinacloudapi.cn/<path>
不建议,因为它可能需要额外的标识配置来读取数据。
Azure 机器学习数据存储上的路径 azureml://datastores/<data_store_name>/paths/<path>
数据资产的路径 azureml:<my_data>:<version>

注意

对于存储上的输入/输出,我们强烈建议使用 Azure 机器学习数据存储路径,而不是直接的 Azure 存储路径。 管道中各种作业类型都支持数据存储路径。

对于数据输入/输出,可以从各种模式中进行选择(下载、装载或上传),以定义如何在计算目标中访问数据。 此表显示了不同类型/模式/输入/输出组合的可能模式。

类型 输入/输出 upload download ro_mount rw_mount direct eval_download eval_mount
uri_folder 输入
uri_file 输入
mltable 输入
uri_folder 输出
uri_file 输出
mltable 输出

注意

在大多数情况下,建议使用 ro_mountrw_mount 模式。 若要了解有关模式的详细信息,请参阅数据资产模式

Azure 机器学习工作室中的视觉对象表示

以下屏幕截图提供了一个示例,说明了如何在 Azure 机器学习工作室的管道作业中显示输入和输出。 此特定作业名为 nyc-taxi-data-regression,可在 azureml-example 中找到。

在工作室的管道作业页中,组件的数据/模型类型输入/输出在相应组件(称为输入/输出端口)中显示为一个小圆圈。 这些端口表示管道中的数据流。

管道级别的输出显示为紫色框,以便于识别。

Screenshot highlighting the pipeline input and output port.

将鼠标悬停在输入/输出端口上时,将显示类型。

Screenshot highlighting the port type when hovering the mouse.

图上不会显示基元类型输入。 可以在管道作业概述面板(用于管道级别输入)或组件面板(用于组件级别输入)的“设置”选项卡中找到它。 以下屏幕截图显示了管道作业的“设置”选项卡,可以通过选择“作业概述”链接将其打开。

如果要检查组件的输入,请双击该组件以打开组件面板。

Screenshot highlighting the job overview setting panel.

同样,在设计器中编辑管道时,可以在“管道接口”面板中找到管道输入和输出,以及在组件面板中找到组件输入和输出(通过双击组件触发)。

Screenshot highlighting the pipeline interface in designer.

如何将组件输入和输出提升到管道级别

通过将组件的输入/输出提升到管道级别,可以在提交管道作业时覆盖组件的输入/输出。 如果要使用 REST 终结点触发管道,这也会非常有用。

下面是将组件输入/输出提升为管道级别输入/输出的示例。

$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json
type: pipeline
display_name: 1b_e2e_registered_components
description: E2E dummy train-score-eval pipeline with registered components

inputs:
  pipeline_job_training_max_epocs: 20
  pipeline_job_training_learning_rate: 1.8
  pipeline_job_learning_rate_schedule: 'time-based'

outputs: 
  pipeline_job_trained_model:
    mode: upload
  pipeline_job_scored_data:
    mode: upload
  pipeline_job_evaluation_report:
    mode: upload

settings:
 default_compute: azureml:cpu-cluster

jobs:
  train_job:
    type: command
    component: azureml:my_train@latest
    inputs:
      training_data: 
        type: uri_folder 
        path: ./data      
      max_epocs: ${{parent.inputs.pipeline_job_training_max_epocs}}
      learning_rate: ${{parent.inputs.pipeline_job_training_learning_rate}}
      learning_rate_schedule: ${{parent.inputs.pipeline_job_learning_rate_schedule}}
    outputs:
      model_output: ${{parent.outputs.pipeline_job_trained_model}}
    services:
      my_vscode:
        type: vs_code
      my_jupyter_lab:
        type: jupyter_lab
      my_tensorboard:
        type: tensor_board
        log_dir: "outputs/tblogs"
    #  my_ssh:
    #    type: tensor_board
    #    ssh_public_keys: <paste the entire pub key content>
    #    nodes: all # Use the `nodes` property to pick which node you want to enable interactive services on. If `nodes` are not selected, by default, interactive applications are only enabled on the head node.

  score_job:
    type: command
    component: azureml:my_score@latest
    inputs:
      model_input: ${{parent.jobs.train_job.outputs.model_output}}
      test_data: 
        type: uri_folder 
        path: ./data
    outputs:
      score_output: ${{parent.outputs.pipeline_job_scored_data}}

  evaluate_job:
    type: command
    component: azureml:my_eval@latest
    inputs:
      scoring_result: ${{parent.jobs.score_job.outputs.score_output}}
    outputs:
      eval_output: ${{parent.outputs.pipeline_job_evaluation_report}}

可以在包含已注册组件的 train-score-eval 管道中找到该完整示例。 此管道将三个输入和三个输出提升到管道级别。 我们以 pipeline_job_training_max_epocs 为例。 它在根级别的 inputs 部分下声明,这意味着它属于管道级别输入。 在 jobs -> train_job 部分下,名为 max_epocs 的输入引用为 ${{parent.inputs.pipeline_job_training_max_epocs}},这指示 train_job 的输入 max_epocs 引用了管道级别输入 pipeline_job_training_max_epocs。 同样,可以使用同一架构提升管道输出。

工作室

可以在设计器“创作”页中将组件的输入提升为管道级别输入。 通过双击组件转到组件的“设置”面板 -> 找到要提升的输入 -> 选择右侧的三个点 -> 选择“添加到管道输入”。

Screenshot highlighting how to promote to pipeline input in designer.

可选输入

默认情况下,所有输入都是必需的,并且每次提交管道作业时,必须分配一个值(或默认值)。 但在某些情况下,可能需要可选输入。 在此类情况下,可以灵活地在提交管道作业时不向输入赋值。

可选输入在以下两种方案中很有用:

  • 如果有可选的数据/模型类型输入,但在提交管道作业时未为其赋值,则管道中将存在缺少上述数据依赖项的组件。 换句话说,输入端口不会链接到任何组件或数据/模型节点。 这会导致管道服务直接调用此组件,而不是等待前面的依赖项准备就绪。

  • 下面的屏幕截图提供了第二个方案的清晰示例。 如果为管道设置了 continue_on_step_failure = True 并有第二个节点 (node2),该节点使用第一个节点 (node1) 的输出作为可选输入,则即使 node1 失败,仍会执行 node2。 但是,如果 node2 使用所需的来自 node1 的输入,则如果 node1 失败,则不会执行第二个节点。

    Screenshot to show the orchestration logic of optional input and continue on failure.

下面是有关如何定义可选输入的示例。

$schema: https://azuremlschemas.azureedge.net/latest/commandComponent.schema.json
name: train_data_component_cli
display_name: train_data
description: A example train component
tags:
  author: azureml-sdk-team
version: 7
type: command
inputs:
  training_data: 
    type: uri_folder
  max_epocs:
    type: integer
    optional: true
  learning_rate: 
    type: number
    default: 0.01
    optional: true
  learning_rate_schedule: 
    type: string
    default: time-based
    optional: true
outputs:
  model_output:
    type: uri_folder
code: ./train_src
environment: azureml:AzureML-sklearn-1.0-ubuntu20.04-py38-cpu:1
command: >-
  python train.py 
  --training_data ${{inputs.training_data}} 
  $[[--max_epocs ${{inputs.max_epocs}}]]
  $[[--learning_rate ${{inputs.learning_rate}}]]
  $[[--learning_rate_schedule ${{inputs.learning_rate_schedule}}]]
  --model_output ${{outputs.model_output}}

当输入设置为 optional = true 时,需要使用 $[[]] 来包括带有输入的命令行。 请参阅上例中突出显示的行。

注意

不支持可选输出。

在管道图中,数据/模型类型的可选输入由虚线圆圈表示。 基元类型的可选输入可以位于“设置”选项卡下。与所需的输入不同,可选输入旁边没有星号,这表示它们不是必需的。

Screenshot highlighting the optional input.

如何自定义输出路径

默认情况下,组件的输出将存储在 azureml://datastores/${{default_datastore}}/paths/${{name}}/${{output_name}} 中。 {default_datastore} 是客户为管道设置的默认数据存储。 如果未设置,则为工作区 Blob 存储。 {name} 是作业名称,它将在作业执行时解析。 {output_name} 是客户在组件 YAML 中定义的输出名称。

但也可以通过定义输出的路径来自定义存储输出的位置。 下面是示例:

pipeline.yaml 定义了具有三个管道级别输出的管道。 可以在包含已注册组件实例的 train-score-eval 管道中找到该完整 YAML。 可以使用以下命令设置 pipeline_job_trained_model 输出的自定义输出路径。

# define the custom output path using datastore uri
# add relative path to your blob container after "azureml://datastores/<datastore_name>/paths"
output_path="azureml://datastores/{datastore_name}/paths/{relative_path_of_container}"  

# create job and define path using --outputs.<outputname>
az ml job create -f ./pipeline.yml --set outputs.pipeline_job_trained_model.path=$output_path  

如何下载输出

可以按照以下示例下载组件的输出或管道输出。

下载管道级别输出

# Download all the outputs of the job
az ml job download --all -n <JOB_NAME> -g <RESOURCE_GROUP_NAME> -w <WORKSPACE_NAME> --subscription <SUBSCRIPTION_ID>

# Download specific output
az ml job download --output-name <OUTPUT_PORT_NAME> -n <JOB_NAME> -g <RESOURCE_GROUP_NAME> -w <WORKSPACE_NAME> --subscription <SUBSCRIPTION_ID>

下载子作业的输出

如果需要下载子作业的输出(未提升到管道级别的组件输出),应首先列出管道作业的所有子作业实体,然后使用类似代码下载输出。

# List all child jobs in the job and print job details in table format
az ml job list --parent-job-name <JOB_NAME> -g <RESOURCE_GROUP_NAME> -w <WORKSPACE_NAME> --subscription <SUBSCRIPTION_ID> -o table

# Select needed child job name to download output
az ml job download --all -n <JOB_NAME> -g <RESOURCE_GROUP_NAME> -w <WORKSPACE_NAME> --subscription <SUBSCRIPTION_ID>

如何将输出注册为命名资产

可以通过将 nameversion 分配给输出来将组件或管道的输出注册为命名资产。 注册的资产可以通过工作室 UI/CLI/SDK 列出在工作区中,也可以在将来的作业中引用。

注册管道输出

display_name: register_pipeline_output
type: pipeline
jobs:
  node:
    type: command
    inputs:
      component_in_path:
        type: uri_file
        path: https://dprepdata.blob.core.chinacloudapi.cn/demo/Titanic.csv
    component: ../components/helloworld_component.yml
    outputs:
      component_out_path: ${{parent.outputs.component_out_path}}
outputs:
  component_out_path:
    type: mltable
    name: pipeline_output  # Define name and version to register pipeline output
    version: '1'
settings:
  default_compute: azureml:cpu-cluster

注册子作业的输出

display_name: register_node_output
type: pipeline
jobs:
  node:
    type: command
    component: ../components/helloworld_component.yml
    inputs:
      component_in_path:
        type: uri_file
        path: 'https://dprepdata.blob.core.chinacloudapi.cn/demo/Titanic.csv'
    outputs:
      component_out_path:
        type: uri_folder
        name: 'node_output'  # Define name and version to register a child job's output
        version: '1'
settings:
  default_compute: azureml:cpu-cluster

后续步骤