使用 CLI (v2) 训练模型

适用于:Azure CLI ml 扩展 v2(当前版本)

Azure 机器学习 CLI (v2) 是一个 Azure CLI 扩展,可以加速模型训练过程,同时可以在 Azure 计算中横向和纵向扩展,并对模型生命周期进行跟踪和审核。

训练机器学习模型通常是一个迭代过程。 使用新式工具能够更快捷轻松地基于更多数据训练更大的模型。 以前繁琐的手动过程(如超参数优化,甚至算法选择)现在通常都可以自动完成。 借助 Azure 机器学习 CLI (v2),可以使用超参数扫描来跟踪工作区中的作业(和模型)、在高性能 Azure 计算中纵向扩展,并利用分布式训练进行横向扩展。

先决条件

提示

对于具有架构验证和作业 YAML 自动完成功能的全功能开发环境,请使用 Visual Studio Code 和 Azure 机器学习扩展

克隆示例存储库

若要运行训练示例,请首先克隆示例存储库,然后更改为 cli 目录:

git clone --depth 1 https://github.com/Azure/azureml-examples
cd azureml-examples/cli

使用 --depth 1 仅克隆对存储库的最新提交,从而减少完成操作的时间。

创建计算

可以从命令行创建 Azure 机器学习计算群集。 例如,以下命令创建一个名为 cpu-cluster 的群集和一个名为 gpu-cluster 的群集。

az ml compute create -n cpu-cluster --type amlcompute --min-instances 0 --max-instances 8

az ml compute create -n gpu-cluster --type amlcompute --min-instances 0 --max-instances 4 --size Standard_NC12

此时你无需支付计算费用,因为在提交作业之前,cpu-clustergpu-cluster 将保留在 0 个节点上。 详细了解如何管理和优化 AmlCompute 的成本

本文的以下示例作业使用 cpu-clustergpu-cluster 之一。 根据需要将本文示例作业中的这些名称调整为你的群集名称。 使用 az ml compute create -h 了解有关计算创建选项的更多详细信息。

Hello world

对于 Azure 机器学习 CLI (v2),作业是以 YAML 格式创作的。 作业聚合:

  • 运行内容
  • 运行方式
  • 运行位置

“hello world”作业包含所有三项:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: echo "hello world"
environment:
  image: python:latest
compute: azureml:cpu-cluster

警告

在用于作业的环境中必须安装 Python。 如果需要,在你的 Dockerfile 中运行 apt-get update -y && apt-get install python3 -y 以安装 Python,或者从已安装 Python 的基础映像中派生。

可运行的对象:

az ml job create -f jobs/basics/hello-world.yml --web

提示

--web 参数将尝试使用默认 Web 浏览器在 Azure 机器学习工作室中打开你的作业。 --stream 参数可用于将日志流式传输到控制台并阻止进一步的命令。

在创建或更新时覆盖值

在创建或更新作业时,可以使用 --set 来覆盖 YAML 作业规范值。 例如:

az ml job create -f jobs/basics/hello-world.yml \
  --set environment.image="python:3.8" \
  --web

作业名称

大部分 az ml job 命令都需要 --name/-ncreatelist 除外),这是工作室中的作业名称或者“运行 ID”。 不应在创建期间直接设置作业的 name 属性,因为该属性在每个工作区中必须是唯一的。 如果未设置,Azure 机器学习会为作业名称生成一个随机 GUID,要获取该随机 GUID,可以在 CLI 中从作业创建的输出中获取,也可以通过在工作室和 MLflow API 中复制“运行 ID”属性。

要在脚本和 CI/CD 流中自动化作业,可以在创建作业时捕获作业的名称,方法是添加 --query name -o tsv 来查询和剥离输出。 具体细节因 shell 而异,但对于 Bash:

run_id=$(az ml job create -f jobs/basics/hello-world.yml --query name -o tsv)

然后在后续命令中使用 $run_id,例如 updateshowstream

az ml job show -n $run_id --web

组织作业

若要组织作业,可以设置显示名称、试验名称、描述和标记。 描述支持工作室中的 markdown 语法。 创建作业后,这些属性是可变的。 完整示例:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: echo "hello world"
environment:
  image: library/python:latest
compute: azureml:cpu-cluster
tags:
  hello: world
display_name: hello-world-example
experiment_name: hello-world-example
description: |
  # Azure Machine Learning "hello world" job

  This is a "hello world" job running in the cloud via Azure Machine Learning!

  ## Description

  Markdown is supported in the studio for job descriptions! You can edit the description there or via CLI.

可以运行此作业,此时这些属性将立即在工作室中可见:

az ml job create -f jobs/basics/hello-world-org.yml --web

使用 --set,可以在创建作业后更新可变值:

az ml job update -n $run_id --set \
  display_name="updated display name" \
  experiment_name="updated experiment name" \
  description="updated description"  \
  tags.hello="updated tag"

环境变量

可以设置环境变量以在作业中使用:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: echo $hello_env_var
environment:
  image: library/python:latest
compute: azureml:cpu-cluster
environment_variables:
  hello_env_var: "hello world"

可以运行此作业:

az ml job create -f jobs/basics/hello-world-env-var.yml --web

警告

command 中,应使用 inputs 将自变量参数化。 请参阅输入和输出

跟踪模型和源代码

生产机器学习模型需要可审计(如果不可重现)。 跟踪给定模型的源代码至关重要。 Azure 机器学习将生成源代码的快照并将其与作业一起保存。 此外,如果你从 Git 存储库运行作业,则会保留源存储库和提交。

提示

如果按照示例存储库进行操作并运行,则可以在工作室中看到迄今为止任何作业运行的源存储库和提交。

可以在作业中指定 code.local_path 键,并以值作为源代码目录的路径。 将生成目录的快照并且与作业一起上传。 可直接从作业的工作目录中获得目录的内容。

警告

源代码不应包含用于模型训练的大数据输入。 请改为使用数据输入。 可以使用源代码目录中的 .gitignore 文件从快照中排除文件。 快照大小的限制为 300 MB 或 2000 个文件。

让我们看一下指定代码的作业:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: python hello-mlflow.py
code: src
environment: azureml:AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest
compute: azureml:cpu-cluster

Python 脚本位于本地源代码目录中。 然后命令调用 python 来运行脚本。 相同的模式可以应用于其他编程语言。

警告

本文中显示的“hello”系列作业仅用于演示目的,不一定遵循推荐的最佳实践。 不建议使用 && 或类似方式按顺序运行多个命令,相反,请考虑将命令写入源代码目录中的脚本文件,并在 command 中调用脚本。 不建议在 command 中安装依赖项,如上所示通过 pip install,而是应将所有作业依赖项指定为环境的一部分。 有关详细信息,请参阅如何使用 CLI (v2) 管理环境

用 MLflow 进行模型跟踪

在迭代模型时,数据科学家需要能够跟踪模型参数和训练指标。 Azure 机器学习与 MLflow 跟踪集成,以支持将模型、工件、指标和参数记录到作业中。 要在 Python 脚本中使用 MLflow,请添加 import mlflow,并在训练代码中调用 mlflow.log_*mlflow.autolog()

警告

mlflowazureml-mlflow 包必须安装在 Python 环境中才能使用 MLflow 跟踪功能。

提示

许多流行框架都支持该调用 mlflow.autolog(),并且该调用将为你处理大部分日志记录。

让我们看一下在上述作业中调用的 Python 脚本,该脚本 mlflow 来记录参数、指标和项目:

# imports
import os
import mlflow

from random import random

# define functions
def main():
    mlflow.log_param("hello_param", "world")
    mlflow.log_metric("hello_metric", random())
    os.system(f"echo 'hello world' > helloworld.txt")
    mlflow.log_artifact("helloworld.txt")


# run functions
if __name__ == "__main__":
    # run main function
    main()

可以通过 Azure 机器学习在云中运行该作业,此时该作业具有可跟踪性和可审计性:

az ml job create -f jobs/basics/hello-mlflow.yml --web

查询指标与 MLflow

运行作业后,你可能需要查询作业的运行结果及其记录的指标。 Python 比 CLI 更适合这项任务。 可以通过 mlflow 来查询运行及其指标并加载到 Pandas 数据帧等熟悉的对象中进行分析。

首先,检索 Azure 机器学习工作区的 MLflow 跟踪 URI:

az ml workspace show --query mlflow_tracking_uri -o tsv

在导入了 MLflow 的 Python 环境中,在 mlflow.set_tracking_uri(<YOUR_TRACKING_URI>) 中使用此命令的输出。 MLflow 调用现在将对应于 Azure 机器学习工作区中的作业。

输入和输出

作业通常包含输入和输出。 输入可以是模型参数,这些参数可能会被扫描以进行超参数优化,也可以是安装或下载到计算目标的云数据输入。 输出(忽略指标)是可以写入或复制到默认输出或命名数据输出的项目。

文字输入

文字输入直接在命令中解析。 可以修改我们的“hello world”作业以使用文字输入:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: |
  echo ${{inputs.hello_string}}
  echo ${{inputs.hello_number}}
environment:
  image: library/python:latest
inputs:
  hello_string: "hello world"
  hello_number: 42
compute: azureml:cpu-cluster

可以运行此作业:

az ml job create -f jobs/basics/hello-world-input.yml --web

可以使用 --set 来覆盖输入:

az ml job create -f jobs/basics/hello-world-input.yml --set \
  inputs.hello_string="hello there" \
  inputs.hello_number=24 \
  --web

作业的文字输入可以转换为搜索空间输入,用于模型训练的超参数扫描。

搜索空间输入

对于扫描作业,可以指定一个搜索空间,以供从中选择文字输入。 有关搜索空间输入的全部选项,请参阅扫描作业 YAML 语法参考

警告

管道作业当前不支持扫描作业。

让我们用一个简单的 Python 脚本来演示这个概念,该脚本接受参数并记录一个随机指标:

# imports
import os
import mlflow
import argparse

from random import random

# define functions
def main(args):
    # print inputs
    print(f"A: {args.A}")
    print(f"B: {args.B}")
    print(f"C: {args.C}")

    # log inputs as parameters
    mlflow.log_param("A", args.A)
    mlflow.log_param("B", args.B)
    mlflow.log_param("C", args.C)

    # log a random metric
    mlflow.log_metric("random_metric", random())


def parse_args():
    # setup arg parser
    parser = argparse.ArgumentParser()

    # add arguments
    parser.add_argument("--A", type=float, default=0.5)
    parser.add_argument("--B", type=str, default="hello world")
    parser.add_argument("--C", type=float, default=1.0)

    # parse args
    args = parser.parse_args()

    # return args
    return args


# run script
if __name__ == "__main__":
    # parse args
    args = parse_args()

    # run main function
    main(args)

并创建相应的扫描作业:

$schema: https://azuremlschemas.azureedge.net/latest/sweepJob.schema.json
type: sweep
trial:
  command: >-
    python hello-sweep.py
    --A ${{inputs.A}}
    --B ${{search_space.B}}
    --C ${{search_space.C}}
  code: src
  environment: azureml:AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest
inputs:
  A: 0.5
compute: azureml:cpu-cluster
sampling_algorithm: random
search_space:
  B:
    type: choice
    values: ["hello", "world", "hello_world"]
  C:
    type: uniform
    min_value: 0.1
    max_value: 1.0
objective:
  goal: minimize
  primary_metric: random_metric
limits:
  max_total_trials: 4
  max_concurrent_trials: 2
  timeout: 3600
display_name: hello-sweep-example
experiment_name: hello-sweep-example
description: Hello sweep job example.

然后运行该扫描作业:

az ml job create -f jobs/basics/hello-sweep.yml --web

数据输入

数据输入解析为作业计算本地文件系统上的路径。 让我们用经典的 Iris 数据集进行演示,该数据集公开托管在 https://azuremlexamples.blob.core.windows.net/datasets/iris.csv

可以编写一个 Python 脚本,将 Iris CSV 文件的路径作为参数,将其读入数据帧,打印前 5 行,并将前 5 行保存到 outputs 目录中。

# imports
import os
import argparse

import pandas as pd

# define functions
def main(args):
    # read in data
    df = pd.read_csv(args.iris_csv)

    # print first 5 lines
    print(df.head())

    # ensure outputs directory exists
    os.makedirs("outputs", exist_ok=True)

    # save data to outputs
    df.to_csv("outputs/iris.csv", index=False)


def parse_args():
    # setup arg parser
    parser = argparse.ArgumentParser()

    # add arguments
    parser.add_argument("--iris-csv", type=str)

    # parse args
    args = parser.parse_args()

    # return args
    return args


# run script
if __name__ == "__main__":
    # parse args
    args = parse_args()

    # run main function
    main(args)

可以指定 Azure 存储 URI 输入,这将装载或下载数据到本地文件系统。 可以指定单个文件:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: |
  echo "--iris-csv: ${{inputs.iris_csv}}"
  python hello-iris.py --iris-csv ${{inputs.iris_csv}}
code: src
inputs:
  iris_csv:
    type: uri_file 
    path: https://azuremlexamples.blob.core.windows.net/datasets/iris.csv
environment: azureml:AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest
compute: azureml:cpu-cluster

然后运行:

az ml job create -f jobs/basics/hello-iris-file.yml --web

也可指定整个文件夹:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: |
  ls ${{inputs.data_dir}}
  echo "--iris-csv: ${{inputs.data_dir}}/iris.csv"
  python hello-iris.py --iris-csv ${{inputs.data_dir}}/iris.csv
code: src
inputs:
  data_dir:
    type: uri_folder 
    path: wasbs://datasets@azuremlexamples.blob.core.windows.net/
environment: azureml:AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest
compute: azureml:cpu-cluster

然后运行:

az ml job create -f jobs/basics/hello-iris-folder.yml --web

专用数据

对于通过数据存储连接到 Azure 机器学习的 Azure Blob 存储或 Azure Data Lake Storage 中的私有数据,可以对输入数据使用 azureml://datastores/<DATASTORE_NAME>/paths/<PATH_TO_DATA> 格式的 Azure 机器学习 URI。 例如,如果将 Iris CSV 上传到 Blob 容器(对应于名为 workspaceblobstore 的数据存储)中名为 /example-data/ 的目录,可以修改之前的作业以使用数据存储中的文件:

警告

如果没有将 Iris CSV 复制到 workspaceblobstore 中的同一位置,则运行这些作业将失败。

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: |
  echo "--iris-csv: ${{inputs.iris_csv}}"
  python hello-iris.py --iris-csv ${{inputs.iris_csv}}
code: src
inputs:
  iris_csv:
    type: uri_file 
    path: azureml://datastores/workspaceblobstore/paths/example-data/iris.csv
environment: azureml:AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest
compute: azureml:cpu-cluster

或整个目录:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: |
  ls ${{inputs.data_dir}}
  echo "--iris-csv: ${{inputs.data_dir}}/iris.csv"
  python hello-iris.py --iris-csv ${{inputs.data_dir}}/iris.csv
code: src
inputs:
  data_dir:
    type: uri_folder 
    path: azureml://datastores/workspaceblobstore/paths/example-data/
environment: azureml:AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest
compute: azureml:cpu-cluster

默认输出

./outputs./logs 目录受到 Azure机器学习的特殊对待。 如果在运行作业期间将任何文件写入这些目录,这些文件将上传到作业,这样,在该作业完成后,你仍可以访问这些文件。 作业完成时将上传 ./outputs 文件夹,而写入 ./logs 的文件将实时上传。 如果你希望在运行作业期间流式传输日志(例如 TensorBoard 日志),请使用后一种上传方式。

可以修改“hello world”作业以输出到默认输出目录中的文件,而不是打印到 stdout

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: echo "hello world" > ./outputs/helloworld.txt
environment:
  image: library/python:latest
compute: azureml:cpu-cluster

可以运行此作业:

az ml job create -f jobs/basics/hello-world-output.yml --web

并下载日志,其中 helloworld.txt 将存在于 <RUN_ID>/outputs/ 目录中:

az ml job download -n $run_id

数据输出

可以指定命名数据输出。 这将在默认数据存储中创建一个目录,默认情况下该目录将被读/写挂载。

可以修改之前的“hello world”作业以写入命名数据输出:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: echo "hello world" > ${{outputs.hello_output}}/helloworld.txt
outputs:
  hello_output:
environment:
  image: python
compute: azureml:cpu-cluster

Hello 管道

管道作业可以并行或按顺序运行多个作业。 如果管道中的步骤之间存在输入/输出依赖关系,则依赖步骤将在其他步骤完成后运行。

可以将“hello world”作业拆分为两个作业:

$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json
type: pipeline
display_name: hello_pipeline
jobs:
  hello_job:
    command: echo "hello"
    environment: azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu@latest
    compute: azureml:cpu-cluster
  world_job:
    command: echo "world"
    environment: azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu@latest
    compute: azureml:cpu-cluster

然后运行该扫描作业:

az ml job create -f jobs/basics/hello-pipeline.yml --web

“hello”和“world”作业将分别并行运行,但前提是计算目标有可用资源。

要在管道中的步骤之间传递数据,请在“hello”作业中定义一个数据输出,并在“world”作业中定义一个相应的输入,也就是先前的输出:

$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json
type: pipeline
display_name: hello_pipeline_io
jobs:
  hello_job:
    command: echo "hello" && echo "world" > ${{outputs.world_output}}/world.txt
    environment: azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu@latest
    compute: azureml:cpu-cluster
    outputs:
      world_output:
  world_job:
    command: cat ${{inputs.world_input}}/world.txt
    environment: azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu:23
    compute: azureml:cpu-cluster
    inputs:
      world_input: ${{parent.jobs.hello_job.outputs.world_output}}

然后运行该扫描作业:

az ml job create -f jobs/basics/hello-pipeline-io.yml --web

这一次,“world”作业将在“hello”作业完成后运行。

为避免在管道中的作业之间复制通用设置,可以在作业之外设置这些设置项:

$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json
type: pipeline
display_name: hello_pipeline_settings

settings:
  default_datestore: azureml:workspaceblobstore
  default_compute: azureml:cpu-cluster
jobs:
  hello_job:
    command: echo 202204190 & echo "hello"
    environment: azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu:23
  world_job:
    command: echo 202204190 & echo "hello"
    environment: azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu:23

可以运行此作业:

az ml job create -f jobs/basics/hello-pipeline-settings.yml --web

单个作业的对应设置将覆盖管道作业的通用设置。 到目前为止的概念可以组合成一个包含作业“A”、“B”和“C”的三步管道作业。 “C”作业对“B”作业有数据依赖,而“A”作业可以独立运行。 “A”作业还将使用单独设置的环境并将其输入之一绑定到顶级管道作业输入:

$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json
type: pipeline
display_name: hello_pipeline_abc
compute: azureml:cpu-cluster
  
inputs:
  hello_string_top_level_input: "hello world"
jobs:
  a:
    command: echo hello ${{inputs.hello_string}}
    environment: azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu@latest
    inputs:
      hello_string: ${{parent.inputs.hello_string_top_level_input}}
  b:
    command: echo "world" >> ${{outputs.world_output}}/world.txt
    environment: azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu@latest
    outputs:
      world_output:
  c:
    command: echo ${{inputs.world_input}}/world.txt
    environment: azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu@latest
    inputs:
      world_input: ${{parent.jobs.b.outputs.world_output}}

可以运行此作业:

az ml job create -f jobs/basics/hello-pipeline-abc.yml --web

训练模型

在 Azure 机器学习中,基本上有两种可能的方法来训练模型:

  1. 利用自动化 ML 用你的数据训练模型,并获得最佳模型。 这种方法通过自动化调整超参数和尝试不同算法的迭代过程来最大限度地提高生产力。
  2. 使用自己的自定义训练脚本训练模型。 此方法的可控性更佳,并允许你自定义训练。

使用自动化 ML 训练模型

自动化 ML 是训练模型的最简单方法,因为你不需要知道训练算法的工作原理,只需提供训练/验证/测试数据集和一些基本配置参数,例如“ML 任务”、“目标列”、“主要指标”、“超时”等,服务将为你训练多个模型并试用各种算法和超参数组合。

通过 CLI (v2) 使用自动化 ML 进行训练时,只需要使用 AutoML 配置创建一个 .YAML 文件,并将其提供给 CLI 以用于创建和提交训练作业。

以下示例演示用于训练分类模型的 AutoML 配置文件,其中,

  • 主要指标是 accuracy
  • 训练超时时间为 180 分钟
  • 训练的数据位于“./training-mltable-folder”文件夹中。 自动化 ML 作业仅接受 MLTable 形式的数据。
$schema: https://azuremlsdk2.blob.core.windows.net/preview/0.0.1/autoMLJob.schema.json
type: automl

experiment_name: dpv2-cli-automl-classifier-experiment
# name: dpv2-cli-classifier-train-job-basic-01
description: A Classification job using bank marketing

compute: azureml:cpu-cluster

task: classification
primary_metric: accuracy

target_column_name: "y"
training_data:
  path: "./training-mltable-folder"
  type: mltable

limits:
  timeout_minutes: 180
  max_trials: 40
  enable_early_termination: true

featurization:
  mode: auto

上面提到的 MLTable 定义是指向训练数据文件的内容,在本例中是一个将自动上传的本地 .csv 文件:

paths:
  - file: ./bank_marketing_train_data.csv
transformations:
  - read_delimited:
        delimiter: ','
        encoding: 'ascii'

最后,可以使用以下 CLI 命令运行它(创建 AutoML 作业):

/> az ml job create --file ./hello-automl-job-basic.yml 

或者如果明确提供工作区 ID 而不是使用默认工作区,则如下所示:

/> az ml job create --file ./hello-automl-job-basic.yml --workspace-name [YOUR_AZURE_WORKSPACE] --resource-group [YOUR_AZURE_RESOURCE_GROUP] --subscription [YOUR_AZURE_SUBSCRIPTION]

要研究使用其他 ML 任务(例如回归、时序预测、图像分类、对象检测、NLP 文本分类等)的其他 AutoML 模型训练示例,请参阅 AutoML CLI 示例的完整列表。

使用自定义脚本训练模型

使用自己的自定义脚本进行训练时,首先需要的是 Python 脚本 (.py),因此让我们将一些 sklearn 代码添加到具有 MLflow 跟踪的 Python 脚本中,以在 Iris CSV 上训练模型:

# imports
import os
import mlflow
import argparse

import pandas as pd

from sklearn.svm import SVC
from sklearn.model_selection import train_test_split

# define functions
def main(args):
    # enable auto logging
    mlflow.autolog()

    # setup parameters
    params = {
        "C": args.C,
        "kernel": args.kernel,
        "degree": args.degree,
        "gamma": args.gamma,
        "coef0": args.coef0,
        "shrinking": args.shrinking,
        "probability": args.probability,
        "tol": args.tol,
        "cache_size": args.cache_size,
        "class_weight": args.class_weight,
        "verbose": args.verbose,
        "max_iter": args.max_iter,
        "decision_function_shape": args.decision_function_shape,
        "break_ties": args.break_ties,
        "random_state": args.random_state,
    }

    # read in data
    df = pd.read_csv(args.iris_csv)

    # process data
    X_train, X_test, y_train, y_test = process_data(df, args.random_state)

    # train model
    model = train_model(params, X_train, X_test, y_train, y_test)


def process_data(df, random_state):
    # split dataframe into X and y
    X = df.drop(["species"], axis=1)
    y = df["species"]

    # train/test split
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.2, random_state=random_state
    )

    # return split data
    return X_train, X_test, y_train, y_test


def train_model(params, X_train, X_test, y_train, y_test):
    # train model
    model = SVC(**params)
    model = model.fit(X_train, y_train)

    # return model
    return model


def parse_args():
    # setup arg parser
    parser = argparse.ArgumentParser()

    # add arguments
    parser.add_argument("--iris-csv", type=str)
    parser.add_argument("--C", type=float, default=1.0)
    parser.add_argument("--kernel", type=str, default="rbf")
    parser.add_argument("--degree", type=int, default=3)
    parser.add_argument("--gamma", type=str, default="scale")
    parser.add_argument("--coef0", type=float, default=0)
    parser.add_argument("--shrinking", type=bool, default=False)
    parser.add_argument("--probability", type=bool, default=False)
    parser.add_argument("--tol", type=float, default=1e-3)
    parser.add_argument("--cache_size", type=float, default=1024)
    parser.add_argument("--class_weight", type=dict, default=None)
    parser.add_argument("--verbose", type=bool, default=False)
    parser.add_argument("--max_iter", type=int, default=-1)
    parser.add_argument("--decision_function_shape", type=str, default="ovr")
    parser.add_argument("--break_ties", type=bool, default=False)
    parser.add_argument("--random_state", type=int, default=42)

    # parse args
    args = parser.parse_args()

    # return args
    return args


# run script
if __name__ == "__main__":
    # parse args
    args = parse_args()

    # run main function
    main(args)

MLflow 支持 scikit-learn 框架以进行自动记录,因此脚本中的单个 mlflow.autolog() 调用将记录所有模型参数、训练指标、模型工件和一些额外的项目(在本例中为混淆矩阵图像)。

要在云中运行,请指定为作业:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
code: src
command: >-
  python main.py 
  --iris-csv ${{inputs.iris_csv}}
  --C ${{inputs.C}}
  --kernel ${{inputs.kernel}}
  --coef0 ${{inputs.coef0}}
inputs:
  iris_csv: 
    type: uri_file
    path: wasbs://datasets@azuremlexamples.blob.core.windows.net/iris.csv
  C: 0.8
  kernel: "rbf"
  coef0: 0.1
environment: azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu@latest
compute: azureml:cpu-cluster
display_name: sklearn-iris-example
experiment_name: sklearn-iris-example
description: Train a scikit-learn SVM on the Iris dataset.

然后运行该扫描作业:

az ml job create -f jobs/single-step/scikit-learn/iris/job.yml --web

若要注册模型,可以将模型文件从运行上传到模型注册表:

az ml model create -n sklearn-iris-example -v 1 -p runs:/$run_id/model --type mlflow_model

扫描超参数

可以修改之前的作业以扫描超参数:

$schema: https://azuremlschemas.azureedge.net/latest/sweepJob.schema.json
type: sweep
trial:
  code: src
  command: >-
    python main.py 
    --iris-csv ${{inputs.iris_csv}}
    --C ${{search_space.C}}
    --kernel ${{search_space.kernel}}
    --coef0 ${{search_space.coef0}}
  environment: azureml:AzureML-sklearn-0.24-ubuntu18.04-py37-cpu@latest
inputs:
  iris_csv: 
    type: uri_file
    path: wasbs://datasets@azuremlexamples.blob.core.windows.net/iris.csv
compute: azureml:cpu-cluster
sampling_algorithm: random
search_space:
  C:
    type: uniform
    min_value: 0.5
    max_value: 0.9
  kernel:
    type: choice
    values: ["rbf", "linear", "poly"]
  coef0:
    type: uniform
    min_value: 0.1
    max_value: 1
objective:
  goal: minimize
  primary_metric: training_f1_score
limits:
  max_total_trials: 20
  max_concurrent_trials: 10
  timeout: 7200
display_name: sklearn-iris-sweep-example
experiment_name: sklearn-iris-sweep-example
description: Sweep hyperparemeters for training a scikit-learn SVM on the Iris dataset.

然后运行该扫描作业:

az ml job create -f jobs/single-step/scikit-learn/iris/job-sweep.yml --web

提示

检查工作室中的“子运行”选项卡以监控进度并查看参数图表。

有关更多扫描选项,请参阅扫描作业 YAML 语法参考

分布式训练

Azure 机器学习支持 PyTorch、TensorFlow 和基于 MPI 的分布式训练。 有关详细信息,请参阅命令作业 YAML 语法参考的分布式部分

例如,可以使用分布式 PyTorch 通过 CIFAR-10 数据集来训练卷积神经网络 (CNN)。 示例存储库中提供了完整脚本。

torchvision 中的 CIFAR-10 数据集需要一个包含 cifar-10-batches-py 目录的目录作为输入。 可以下载压缩的源代码并解压到本地目录:

mkdir data

wget "https://azuremlexamples.blob.core.windows.net/datasets/cifar-10-python.tar.gz"

tar -xvzf cifar-10-python.tar.gz -C data

然后从本地目录创建 Azure 机器学习数据集,该数据集将上传到默认数据存储:

az ml data create --name cifar-10-example --version 1 --set path=data

(可选)删除本地文件和目录:

rm cifar-10-python.tar.gz

rm -r data

可以使用数据输入的 dataset 键在作业中引用数据集(仅限文件)。 格式是 azureml:<DATASET_NAME>:<DATASET_VERSION>,所以对于刚刚创建的 CIFAR-10 数据集,格式为 azureml:cifar-10-example:1

有了数据集,就可以编写分布式 PyTorch 作业来训练我们的模型:

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
code: src
command: >-
  python train.py 
  --epochs ${{inputs.epochs}}
  --learning-rate ${{inputs.learning_rate}}
  --data-dir ${{inputs.cifar}}
inputs:
  epochs: 1
  learning_rate: 0.2
  cifar: 
     type: uri_folder
     path: azureml:cifar-10-example:1
environment: azureml:AzureML-pytorch-1.9-ubuntu18.04-py37-cuda11-gpu@latest
compute: azureml:gpu-cluster
distribution:
  type: pytorch 
  process_count_per_instance: 1
resources:
  instance_count: 2
display_name: pytorch-cifar-distributed-example
experiment_name: pytorch-cifar-distributed-example
description: Train a basic convolutional neural network (CNN) with PyTorch on the CIFAR-10 dataset, distributed via PyTorch.

然后运行该扫描作业:

az ml job create -f jobs/single-step/pytorch/cifar-distributed/job.yml --web

构建训练管道

上面的 CIFAR-10 示例可以很好地转换为管道作业。 之前的作业可以拆分为三个作业以在管道中进行编排:

  • “get-data”,用于运行 Bash 脚本以下载和提取 cifar-10-batches-py
  • “train-model”,用于获取数据并使用分布式 PyTorch 训练模型
  • “eval-model”,用于获取数据和已经训练的模型并评估精确性

“train-model”和“eval-model”都依赖于“get-data”作业的输出。 此外,“eval-model”将依赖于“train-model”作业的输出。 因此,这三个作业将按顺序运行。

也可以使用可重用的组件来编写管道。 有关详细信息,请参阅使用 Azure 机器学习 CLI 创建和运行基于组件的机器学习管道(预览版)

后续步骤