从 Batch AI 迁移到 Azure 机器学习服务

Azure Batch AI 服务即将在 3 月停用。 Batch AI 的大规模培训和评分功能现在可在 Azure 机器学习服务中获取,该服务已于 2018 年 12 月 4 日正式发布。

除了许多其他机器学习功能外,Azure 机器学习服务还包括基于云的托管计算目标,用于培训、部署和对机器学习模型评分。 此计算目标称为 Azure 机器学习计算。 开始迁移并立即使用。 可以通过 Azure 机器学习服务 Python SDK、命令行界面和 Azure 门户与 Azure 机器学习服务进行交互。

从 Batch AI 预览版升级到 Azure 机器学习服务正式版后,可以通过估算器和数据存储等更易用的概念来获得更好的体验。 此外,还能保证获得正式版 Azure 服务的 SLA 保障和客户支持。

Azure 机器学习服务还引入了自动化机器学习、超参数优化和机器学习管道等新功能,在大部分的大规模 AI 工作负荷中,这些功能非常有用。 无需切换到单独的服务即可部署训练的模型,这有助于完成整个数据科学循环:从准备数据(使用数据准备 SDK),到操作化和模型监视。

开始迁移

要避免应用程序中断并确保可使用最新功能,请在 2019 年 3 月 31 日之前执行以下步骤:

  1. 创建 Azure 机器学习服务工作区并开始使用:

  2. 安装 Azure 机器学习 SDK数据准备 SDK

  3. 为模型定型设置 Azure 机器学习计算

  4. 更新脚本以使用 Azure 机器学习计算。 以下部分介绍适用于 Batch AI 的常用代码如何映射到适用于 Azure 机器学习的代码。

创建工作区

在 Azure Batch AI 中使用 configuration.json 初始化工作区的概念类似于在 Azure 机器学习服务中使用配置文件。

Batch AI 中使用的代码如下:

sys.path.append('../../..')
import utilities as utils

cfg = utils.config.Configuration('../../configuration.json')
client = utils.config.create_batchai_client(cfg)

utils.config.create_resource_group(cfg)
_ = client.workspaces.create(cfg.resource_group, cfg.workspace, cfg.location).result()

Azure 机器学习服务中,可以尝试:

from azureml.core.workspace import Workspace

ws = Workspace.from_config()
print('Workspace name: ' + ws.name, 
      'Azure region: ' + ws.location, 
      'Subscription id: ' + ws.subscription_id, 
      'Resource group: ' + ws.resource_group, sep = '\n')

此外,还可以通过指定配置参数来直接创建工作区,如下所示

from azureml.core import Workspace
# Create the workspace using the specified parameters
ws = Workspace.create(name = workspace_name,
                      subscription_id = subscription_id,
                      resource_group = resource_group, 
                      location = workspace_region,
                      create_resource_group = True,
                      exist_ok = True)
ws.get_details()

# write the details of the workspace to a configuration file to the notebook library
ws.write_config()

SDK 参考文档中详细了解 Azure 机器学习工作区类。

创建计算群集

Azure 机器学习支持多个计算目标,其中的某些目标由附加到工作区的不同服务(例如 HDInsight 群集或远程 VM)管理。 详细了解各种计算目标。 创建 Azure Batch AI 计算群集的概念对应于在 Azure 机器学习服务中创建 AmlCompute 群集。 创建 Amlcompute 采用计算配置,这类似于在 Azure Batch AI 中传递参数。 需要注意的一点是,自动缩放在 AmlCompute 群集上默认已启用,而在 Azure Batch AI 中默认已禁用。

Batch AI 中使用的代码如下:

nodes_count = 2
cluster_name = 'nc6'

parameters = models.ClusterCreateParameters(
    vm_size='STANDARD_NC6',
    scale_settings=models.ScaleSettings(
        manual=models.ManualScaleSettings(target_node_count=nodes_count)
    ),
    user_account_settings=models.UserAccountSettings(
        admin_user_name=cfg.admin,
        admin_user_password=cfg.admin_password or None,
        admin_user_ssh_public_key=cfg.admin_ssh_key or None,
    )
)
_ = client.clusters.create(cfg.resource_group, cfg.workspace, cluster_name, parameters).result()

Azure 机器学习服务中,可以尝试:

from azureml.core.compute import ComputeTarget, AmlCompute
from azureml.core.compute_target import ComputeTargetException

# Choose a name for your CPU cluster
gpu_cluster_name = "nc6"

# Verify that cluster does not exist already
try:
    gpu_cluster = ComputeTarget(workspace=ws, name=gpu_cluster_name)
    print('Found existing cluster, use it.')
except ComputeTargetException:
    compute_config = AmlCompute.provisioning_configuration(vm_size='STANDARD_NC6',
                                                           vm_priority='lowpriority',
                                                           min_nodes=1,
                                                           max_nodes=2,
                                                           idle_seconds_before_scaledown='300',
                                                           vnet_resourcegroup_name='<my-resource-group>',
                                                           vnet_name='<my-vnet-name>',
                                                           subnet_name='<my-subnet-name>')
    gpu_cluster = ComputeTarget.create(ws, gpu_cluster_name, compute_config)

gpu_cluster.wait_for_completion(show_output=True)

SDK 参考文档中详细了解 AMLCompute 类。 请注意,在上述配置中,只有 vm_size 和 max_nodes 是必需的,剩余的属性(例如 VNet)仅适用于高级群集设置。

监视群集的状态

如下所示,在 Azure 机器学习服务中可以更直接地监视群集状态。

Batch AI 中使用的代码如下:

cluster = client.clusters.get(cfg.resource_group, cfg.workspace, cluster_name)
utils.cluster.print_cluster_status(cluster)

Azure 机器学习服务中,可以尝试:

gpu_cluster.get_status().serialize()

获取对存储帐户的引用

在 Azure 机器学习服务中,Blob 等数据存储的概念已使用数据存储对象进行简化。 默认情况下,Azure 机器学习服务工作区会创建存储帐户,但你也可以在创建工作区的过程中附加自己的存储。

Batch AI 中使用的代码如下:

azure_blob_container_name = 'batchaisample'
blob_service = BlockBlobService(cfg.storage_account_name, cfg.storage_account_key)
blob_service.create_container(azure_blob_container_name, fail_on_exist=False)

Azure 机器学习服务中,可以尝试:

ds = ws.get_default_datastore()
print(ds.datastore_type, ds.account_name, ds.container_name)

Azure 机器学习服务文档中详细了解如何注册其他存储帐户,或获取对另一个已注册的数据存储的引用。

下载和上传数据

在任一服务中,都可以使用上述数据存储引用轻松将数据上传到存储帐户。 在 Azure Batch AI 中,我们还会部署训练脚本作为文件共享的一部分,不过,在 Azure 机器学习服务中,可将训练脚本指定为作业配置的一部分。

Batch AI 中使用的代码如下:

mnist_dataset_directory = 'mnist_dataset'
utils.dataset.download_and_upload_mnist_dataset_to_blob(
    blob_service, azure_blob_container_name, mnist_dataset_directory)

script_directory = 'tensorflow_samples'
script_to_deploy = 'mnist_replica.py'

blob_service.create_blob_from_path(azure_blob_container_name,
                                   script_directory + '/' + script_to_deploy, 
                                   script_to_deploy)

Azure 机器学习服务中,可以尝试:

import os
import urllib
os.makedirs('./data', exist_ok=True)
download_url = 'https://s3.amazonaws.com/img-datasets/mnist.npz'
urllib.request.urlretrieve(download_url, filename='data/mnist.npz')

ds.upload(src_dir='data', target_path='mnist_dataset', overwrite=True, show_progress=True)

path_on_datastore = ' mnist_dataset/mnist.npz' ds_data = ds.path(path_on_datastore) print(ds_data)

创建试验

如前所述,类似于 Azure Batch AI,Azure 机器学习服务中存在试验的概念。 每个试验可以包含不同的运行,类似于 Azure Batch AI 中的作业。 Azure 机器学习服务还允许针对每个父运行下的各个子运行创建层次结构。

Batch AI 中使用的代码如下:

experiment_name = 'tensorflow_experiment'
experiment = client.experiments.create(cfg.resource_group, cfg.workspace, experiment_name).result()

Azure 机器学习服务中,可以尝试:

from azureml.core import Experiment

experiment_name = 'tensorflow_experiment'
experiment = Experiment(ws, name=experiment_name)

提交作业

创建试验后,可通过多种不同的方式提交运行。 此示例尝试使用 TensorFlow 创建深度学习模型,并使用 Azure 机器学习服务估算器来执行该操作。 估算器只是基础运行配置中的一个包装器函数,它可以简化运行的提交,目前仅受 Pytorch 和 TensorFlow 的支持。 通过数据存储的概念,还可以轻松指定装载路径

Batch AI 中使用的代码如下:

azure_file_share = 'afs'
azure_blob = 'bfs'
args_fmt = '--job_name={0} --num_gpus=1 --train_steps 10000 --checkpoint_dir=$AZ_BATCHAI_OUTPUT_MODEL --log_dir=$AZ_BATCHAI_OUTPUT_TENSORBOARD --data_dir=$AZ_BATCHAI_INPUT_DATASET --ps_hosts=$AZ_BATCHAI_PS_HOSTS --worker_hosts=$AZ_BATCHAI_WORKER_HOSTS --task_index=$AZ_BATCHAI_TASK_INDEX'

parameters = models.JobCreateParameters(
     cluster=models.ResourceId(id=cluster.id),
     node_count=2,
     input_directories=[
        models.InputDirectory(
            id='SCRIPT',
            path='$AZ_BATCHAI_JOB_MOUNT_ROOT/{0}/{1}'.format(azure_blob, script_directory)),
        models.InputDirectory(
            id='DATASET',
            path='$AZ_BATCHAI_JOB_MOUNT_ROOT/{0}/{1}'.format(azure_blob, mnist_dataset_directory))],
     std_out_err_path_prefix='$AZ_BATCHAI_JOB_MOUNT_ROOT/{0}'.format(azure_file_share),
     output_directories=[
        models.OutputDirectory(
            id='MODEL',
            path_prefix='$AZ_BATCHAI_JOB_MOUNT_ROOT/{0}'.format(azure_file_share),
            path_suffix='Models'),
        models.OutputDirectory(
            id='TENSORBOARD',
            path_prefix='$AZ_BATCHAI_JOB_MOUNT_ROOT/{0}'.format(azure_file_share),
            path_suffix='Logs')
     ],
     mount_volumes=models.MountVolumes(
            azure_file_shares=[
                models.AzureFileShareReference(
                    account_name=cfg.storage_account_name,
                    credentials=models.AzureStorageCredentialsInfo(
                        account_key=cfg.storage_account_key),
                    azure_file_url='https://{0}.file.core.windows.net/{1}'.format(
                        cfg.storage_account_name, azure_file_share_name),
                    relative_mount_path=azure_file_share)
            ],
            azure_blob_file_systems=[
                models.AzureBlobFileSystemReference(
                    account_name=cfg.storage_account_name,
                    credentials=models.AzureStorageCredentialsInfo(
                        account_key=cfg.storage_account_key),
                    container_name=azure_blob_container_name,
                    relative_mount_path=azure_blob)
            ]
        ),
     container_settings=models.ContainerSettings(
         image_source_registry=models.ImageSourceRegistry(image='tensorflow/tensorflow:1.8.0-gpu')),
     tensor_flow_settings=models.TensorFlowSettings(
         parameter_server_count=1,
         worker_count=nodes_count,
         python_script_file_path='$AZ_BATCHAI_INPUT_SCRIPT/'+ script_to_deploy,
         master_command_line_args=args_fmt.format('worker'),
         worker_command_line_args=args_fmt.format('worker'),
         parameter_server_command_line_args=args_fmt.format('ps'),
     )
)

在 Azure Batch AI 中提交作业本身的过程是通过 create 函数完成的。

job_name = datetime.utcnow().strftime('tf_%m_%d_%Y_%H%M%S')
job = client.jobs.create(cfg.resource_group, cfg.workspace, experiment_name, job_name, parameters).result()
print('Created Job {0} in Experiment {1}'.format(job.name, experiment.name))

Azure Batch AI 示例 Notebook github 存储库中可以找到有关此训练代码片段的完整信息(包括我们已上传到上述文件共享的 mnist_replica.py 文件)。

Azure 机器学习服务中,可以尝试:

from azureml.train.dnn import TensorFlow

script_params={
    '--num_gpus': 1,
    '--train_steps': 500,
    '--input_data': ds_data.as_mount()

}

estimator = TensorFlow(source_directory=project_folder,
                       compute_target=gpu_cluster,
                       script_params=script_params,
                       entry_script='tf_mnist_replica.py',
                       node_count=2,
                       worker_count=2,
                       parameter_server_count=1,   
                       distributed_backend='ps',
                       use_gpu=True)

Azure 机器学习服务示例 Notebook github 存储库中可以找到有关此训练代码片段的完整信息(包括 tf_mnist_replica.py 文件)。 数据存储本身可以装载在单个节点上,或者,可以在节点本身上下载训练数据。 Azure 机器学习服务文档中提供了有关在估算器中引用数据存储的更多详细信息。

在 Azure 机器学习服务中提交运行的过程是通过 submit 函数完成的。

run = experiment.submit(estimator)
print(run)

可通过另一种方式指定运行的参数,即使用运行配置 – 定义自定义训练环境时,此方法尤其有用。 可以在此示例 AmlCompute Notebook 中找到更多详细信息。

监视运行

提交运行后,可以等待该运行完成,或者使用可直接从代码中调用的简洁 Jupyter 小组件,在 Azure 机器学习服务中对其进行监视。 此外,可以通过循环访问工作区中的各个试验以及每个试验中的各个运行,来提取以前的任一运行的上下文。

Batch AI 中使用的代码如下:

utils.job.wait_for_job_completion(client, cfg.resource_group, cfg.workspace, 
                                  experiment_name, job_name, cluster_name, 'stdouterr', 'stdout-wk-0.txt')

files = client.jobs.list_output_files(cfg.resource_group, cfg.workspace, experiment_name, job_name,
                                      models.JobsListOutputFilesOptions(outputdirectoryid='stdouterr')) 
for f in list(files):
    print(f.name, f.download_url or 'directory')

Azure 机器学习服务中,可以尝试:

run.wait_for_completion(show_output=True)

from azureml.widgets import RunDetails
RunDetails(run).show()

下面是在笔记本中加载小组件以实时查看日志的方式快照:小组件监视图

编辑群集

删除群集的过程非常直截了当。 此外,如果你想要将某个群集扩展为包含更多的节点,或者在缩减群集之前增大空闲等待时间,Azure 机器学习服务还允许从 Notebook 内部更新该群集。 我们不允许更改群集本身的 VM 大小,因为这需要在后端有效地进行新的部署。

Batch AI 中使用的代码如下:

_ = client.clusters.delete(cfg.resource_group, cfg.workspace, cluster_name)

Azure 机器学习服务中,可以尝试:

gpu_cluster.delete()

gpu_cluster.update(min_nodes=2, max_nodes=4, idle_seconds_before_scaledown=600)

获取支持

Batch AI 定于 3 月 31 日停用,并且已阻止新订阅针对服务注册,除非它通过支持提出异常将其列入允许列表。 如有任何疑问,或者在迁移到 Azure 机器学习服务的过程中想要提供反馈,请通过 Azure Batch AI 训练预览版联系我们。

Azure 机器学习服务现已推出正式版。 这意味着,它附带了经过承诺的 SLA,并且有多种支持计划可供选择。

通过 Azure Batch AI 服务或通过 Azure 机器学习服务使用 Azure 基础结构的定价不应有所不同,因为在这两种情况下,我们仅收取基础计算的价格。 有关详细详细,请参阅定价计算器

Azure 门户中查看这两个服务的可用区域。

后续步骤