无服务器计算上的模型训练

适用范围:Azure CLI ml 扩展 v2(当前版本)Python SDK azure-ai-ml v2(当前版本)

不再需要创建和管理计算,即能以可缩放的方式训练模型。 可以改为将作业提交到名为“无服务器计算”的新计算目标类型。 无服务器计算是在 Azure 机器学习上运行训练作业的最简单方法。 无服务器计算是完全托管的按需计算。 Azure 机器学习为你创建、缩放和管理计算。 通过无服务器计算的模型训练,机器学习专业人员可以专注于他们构建机器学习模型的专业知识,无需了解计算基础结构或对其进行设置。

机器学习专业人员可以指定作业所需的资源。 Azure 机器学习管理计算基础结构,并提供托管网络隔离以减轻你的负担。

企业还可以通过为每个作业指定最佳资源来降低成本。 IT 管理员仍可以通过在订阅和工作区级别指定核心配额以及应用 Azure 策略来应用控制措施。

无服务器计算可用于微调模型目录中的模型,例如 LLAMA 2。 无服务器计算可用于从 Azure 机器学习工作室、SDK 和 CLI 运行所有类型的作业。 无服务器计算还可用于生成环境映像和负责任 AI 仪表板方案。 无服务器作业使用与 Azure 机器学习计算配额相同的配额。 可以选择标准(专用)层或现成(低优先级)VM。 无服务器作业支持托管标识和用户标识。 计费模型与 Azure 机器学习计算相同。

无服务器计算的优点

  • Azure 机器学习可管理基础结构的创建、设置、缩放、删除、修补和计算,从而减少管理开销
  • 无需了解计算、各种计算类型和相关属性。
  • 无需为所需的每个 VM 大小重复创建群集,使用相同的设置并为每个工作区复制。
  • 可以通过在实例类型(VM 大小)和实例计数方面指定每个作业在运行时所需的确切资源来优化成本。 可以监视作业的利用率指标,以优化作业所需的资源。
  • 减少运行作业所涉及的步骤
  • 若要进一步简化作业提交,可以完全跳过资源。 Azure 机器学习默认设置实例计数,并根据配额、成本、性能和磁盘大小等因素选择实例类型(VM 大小)。
  • 在某些情况下可缩短作业开始执行前的等待时间。
  • 作业提交支持用户标识和工作区用户分配的托管标识。
  • 使用托管网络隔离,可以简化和自动化网络隔离配置。 还支持客户虚拟网络
  • 通过配额和 Azure 策略进行管理员控制

如何使用无服务器计算

  • 可以使用笔记本微调 LLAMA 2 等基础模型,如下所示:

  • 创建自己的计算群集时,在命令作业中使用其名称,例如 compute="cpu-cluster"。 使用无服务器时,可以跳过计算群集的创建,省略 compute 参数,改用无服务器计算。 如果未为作业指定 compute,则作业在无服务器计算上运行。 在 CLI 或 SDK 作业中省略计算名称,以在以下作业类型中使用无服务器计算,并选择性地提供作业在实例计数和实例类型方面所需的资源:

    • 命令作业,包括交互式作业和分布式训练
    • AutoML 作业
    • 扫描作业
    • 并行作业
  • 对于通过 CLI 的管道作业,将 default_compute: azureml:serverless 用于管道级别默认计算。 对于通过 SDK 的管道作业,使用 default_compute="serverless"。 有关示例,请参阅管道作业

  • 在工作室中提交训练作业(预览)时,选择“无服务器”作为计算类型。

  • 使用 Azure 机器学习设计器时,选择“无服务器”作为默认计算。

  • 可以使用无服务器计算来实现负责任 AI 仪表板

性能注意事项

无服务器计算可通过以下方式帮助加快训练速度:

配额不足:创建自己的计算群集时,你需要负责确定要创建的 VM 大小和节点计数。 作业运行时,如果没有足够的用于群集的配额,作业将失败。 默认情况下,无服务器计算使用有关配额的信息来选择适当的 VM 大小。

纵向缩减优化:当计算群集纵向缩减时,新作业必须等待纵向缩减发生,然后纵向扩展,作业才会运行。 使用无服务器计算时,无需等待纵向缩减,作业可以开始在另一个群集/节点上运行(假设你有配额)。

群集忙碌优化:当作业在计算群集上运行并且另一个作业已提交时,你的作业将排在当前正在运行的作业后面。 使用无服务器计算时,可以获取另一个节点/另一个群集来开始运行作业(假设你有配额)。

Quota

提交作业时,仍需要足够的 Azure 机器学习计算配额才能继续(工作区和订阅级别的配额)。 基于此配额选择无服务器作业的默认 VM 大小。 如果指定自己的 VM 大小/系列:

  • 如果 VM 大小/系列有一些配额,但没有足够的实例数配额,则会看到错误。 此错误建议根据配额限制将实例数减少到有效数目,或者请求增加此 VM 系列的配额或更改 VM 大小
  • 如果没有指定 VM 大小的配额,则会看到错误。 错误建议选择你有配额的其他 VM 大小或为此 VM 系列请求配额
  • 如果 VM 系列有足够的配额来运行无服务器作业,但其他作业正在使用配额,则你会收到一条消息,指出作业必须在队列中等待,直到配额可用

在 Microsoft Azure 门户中查看使用情况和配额时,会看到名称“无服务器”以查看无服务器作业使用的所有配额。

标识支持和凭据传递

  • 用户凭据传递:无服务器计算完全支持用户凭据传递。 提交作业的用户的用户令牌用于存储访问。 这些凭据来自 Microsoft Entra ID。

    from azure.ai.ml import command
    from azure.ai.ml import MLClient     # Handle to the workspace
    from azure.identity import DefaultAzureCredential     # Authentication package
    from azure.ai.ml.entities import ResourceConfiguration
    from azure.ai.ml.entities import UserIdentityConfiguration 
    
    credential = DefaultAzureCredential()
    # Get a handle to the workspace. You can find the info on the workspace tab on studio.ml.azure.cn
    ml_client = MLClient(
        credential=credential,
        subscription_id="<Azure subscription id>", 
        resource_group_name="<Azure resource group>",
        workspace_name="<Azure Machine Learning Workspace>",
    )
    job = command(
        command="echo 'hello world'",
        environment="AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest",
            identity=UserIdentityConfiguration(),
    )
    # submit the command job
    ml_client.create_or_update(job)
    
  • 用户分配的托管标识:如果工作区配置了用户分配的托管标识,则可以将该标识与无服务器作业一起使用,以便进行存储访问。

    from azure.ai.ml import command
    from azure.ai.ml import MLClient     # Handle to the workspace
    from azure.identity import DefaultAzureCredential    # Authentication package
    from azure.ai.ml.entities import ResourceConfiguration
    from azure.ai.ml.entities import ManagedIdentityConfiguration
    
    credential = DefaultAzureCredential()
    # Get a handle to the workspace. You can find the info on the workspace tab on studio.ml.azure.cn
    ml_client = MLClient(
        credential=credential,
        subscription_id="<Azure subscription id>", 
        resource_group_name="<Azure resource group>",
        workspace_name="<Azure Machine Learning Workspace>",
    )
    job = command(
        command="echo 'hello world'",
        environment="AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest",
            identity= ManagedIdentityConfiguration(),
    )
    # submit the command job
    ml_client.create_or_update(job)
    
    

有关附加用户分配的托管标识的信息,请参阅附加用户分配的托管标识

配置命令作业的属性

如果未为命令、扫描和 AutoML 作业指定计算目标,则计算默认为无服务器计算。 例如,对于此命令作业:

from azure.ai.ml import command
from azure.ai.ml import command 
from azure.ai.ml import MLClient # Handle to the workspace
from azure.identity import DefaultAzureCredential # Authentication package

credential = DefaultAzureCredential()
# Get a handle to the workspace. You can find the info on the workspace tab on studio.ml.azure.cn
ml_client = MLClient(
    credential=credential,
    subscription_id="<Azure subscription id>", 
    resource_group_name="<Azure resource group>",
    workspace_name="<Azure Machine Learning Workspace>",
)
job = command(
    command="echo 'hello world'",
    environment="AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest",
)
# submit the command job
ml_client.create_or_update(job)

计算默认为无服务器计算:

  • 此作业的单节点。 默认节点数基于作业类型。 有关其他作业类型,请参阅以下部分。
  • CPU 虚拟机,根据配额、性能、成本和磁盘大小确定。
  • 专用虚拟机
  • 工作区位置

可以替代这些默认值。 如果要为无服务器计算指定 VM 类型或节点数,请将 resources 添加到作业:

  • instance_type,选择特定的 VM。 如果需要特定的 CPU/GPU VM 大小,请使用此参数

  • instance_count,指定节点数。

    from azure.ai.ml import command 
    from azure.ai.ml import MLClient # Handle to the workspace
    from azure.identity import DefaultAzureCredential # Authentication package
    from azure.ai.ml.entities import JobResourceConfiguration 
    
    credential = DefaultAzureCredential()
    # Get a handle to the workspace. You can find the info on the workspace tab on studio.ml.azure.cn
    ml_client = MLClient(
        credential=credential,
        subscription_id="<Azure subscription id>", 
        resource_group_name="<Azure resource group>",
        workspace_name="<Azure Machine Learning Workspace>",
    )
    job = command(
        command="echo 'hello world'",
        environment="AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest",
        resources = JobResourceConfiguration(instance_type="Standard_NC24", instance_count=4)
    )
    # submit the command job
    ml_client.create_or_update(job)
    
  • 若要更改作业层,请使用 queue_settings 在专用 VM (job_tier: Standard) 和低优先级 (jobtier: Spot) 之间选择。

    from azure.ai.ml import command
    from azure.ai.ml import MLClient    # Handle to the workspace
    from azure.identity import DefaultAzureCredential    # Authentication package
    credential = DefaultAzureCredential()
    # Get a handle to the workspace. You can find the info on the workspace tab on studio.ml.azure.cn
    ml_client = MLClient(
        credential=credential,
        subscription_id="<Azure subscription id>", 
        resource_group_name="<Azure resource group>",
        workspace_name="<Azure Machine Learning Workspace>",
    )
    job = command(
        command="echo 'hello world'",
        environment="AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest",
        queue_settings={
          "job_tier": "spot"  
        }
    )
    # submit the command job
    ml_client.create_or_update(job)
    

命令作业的所有字段的示例

下面是指定的所有字段的示例,包括作业应使用的标识。 无需指定虚拟网络设置,因为会自动使用工作区级别的托管网络隔离。

from azure.ai.ml import command
from azure.ai.ml import MLClient      # Handle to the workspace
from azure.identity import DefaultAzureCredential     # Authentication package
from azure.ai.ml.entities import ResourceConfiguration
from azure.ai.ml.entities import UserIdentityConfiguration 

credential = DefaultAzureCredential()
# Get a handle to the workspace. You can find the info on the workspace tab on studio.ml.azure.cn
ml_client = MLClient(
    credential=credential,
    subscription_id="<Azure subscription id>", 
    resource_group_name="<Azure resource group>",
    workspace_name="<Azure Machine Learning Workspace>",
)
job = command(
    command="echo 'hello world'",
    environment="AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest",
         identity=UserIdentityConfiguration(),
    queue_settings={
      "job_tier": "Standard"  
    }
)
job.resources = ResourceConfiguration(instance_type="Standard_E4s_v3", instance_count=1)
# submit the command job
ml_client.create_or_update(job)

若要查看使用无服务器计算进行训练的更多示例,请参阅:

AutoML 作业

无需为 AutoML 作业指定计算。 可以选择性地指定资源。 如果未指定实例计数,则根据 max_concurrent_trials 和 max_nodes 参数进行默认设置。 如果提交无实例类型的 AutoML 图像分类或 NLP 任务,则会自动选择 GPU VM 大小。 可以通过 CLI、SDK 或 Studio 提交 AutoML 作业。 若要在工作室中使用无服务器计算提交 AutoML 作业,请首先在预览面板中启用在工作室中提交训练作业(预览)功能。

如果要指定类型或实例计数,使用 ResourceConfiguration 类。

# Create the AutoML classification job with the related factory-function.
from azure.ai.ml.entities import ResourceConfiguration 

classification_job = automl.classification(
    experiment_name=exp_name,
    training_data=my_training_data_input,
    target_column_name="y",
    primary_metric="accuracy",
    n_cross_validations=5,
    enable_model_explainability=True,
    tags={"my_custom_tag": "My custom value"},
)

# Limits are all optional
classification_job.set_limits(
    timeout_minutes=600,
    trial_timeout_minutes=20,
    max_trials=max_trials,
    # max_concurrent_trials = 4,
    # max_cores_per_trial: -1,
    enable_early_termination=True,
)

# Training properties are optional
classification_job.set_training(
    blocked_training_algorithms=[ClassificationModels.LOGISTIC_REGRESSION],
    enable_onnx_compatible_models=True,
)

# Serverless compute resources used to run the job
classification_job.resources = 
ResourceConfiguration(instance_type="Standard_E4s_v3", instance_count=6)

管道作业

对于管道作业,将 "serverless" 指定为默认计算类型以使用无服务器计算。

# Construct pipeline
@pipeline()
def pipeline_with_components_from_yaml(
    training_input,
    test_input,
    training_max_epochs=20,
    training_learning_rate=1.8,
    learning_rate_schedule="time-based",
):
    """E2E dummy train-score-eval pipeline with components defined via yaml."""
    # Call component obj as function: apply given inputs & parameters to create a node in pipeline
    train_with_sample_data = train_model(
        training_data=training_input,
        max_epochs=training_max_epochs,
        learning_rate=training_learning_rate,
        learning_rate_schedule=learning_rate_schedule,
    )

    score_with_sample_data = score_data(
        model_input=train_with_sample_data.outputs.model_output, test_data=test_input
    )
    score_with_sample_data.outputs.score_output.mode = "upload"

    eval_with_sample_data = eval_model(
        scoring_result=score_with_sample_data.outputs.score_output
    )

    # Return: pipeline outputs
    return {
        "trained_model": train_with_sample_data.outputs.model_output,
        "scored_data": score_with_sample_data.outputs.score_output,
        "evaluation_report": eval_with_sample_data.outputs.eval_output,
    }


pipeline_job = pipeline_with_components_from_yaml(
    training_input=Input(type="uri_folder", path=parent_dir + "/data/"),
    test_input=Input(type="uri_folder", path=parent_dir + "/data/"),
    training_max_epochs=20,
    training_learning_rate=1.8,
    learning_rate_schedule="time-based",
)

# set pipeline to use serverless compute
pipeline_job.settings.default_compute = "serverless"

还可以在设计器中将无服务器计算设置为默认计算。

后续步骤

若要查看使用无服务器计算进行训练的更多示例,请参阅: