关于 ml-azureml-adf-automation
用于在 CI 中自动注册 Azure Machine Learning 代码资源,并将注册版本传入 Azure Data Factory 工作流的技能。强调以 SDK 返回的版本为准,并在运行时验证网络和依赖项。
主要功能
- 01在 CI 中注册 Azure ML 代码资源
- 02传递 SDK 返回的资源版本
- 03通过指针 Blob 传递版本
- 04配置 ADF WebActivity 网络
- 05验证私有存储访问
- 06固定 Azure ML SDK 依赖
适用场景
- 01自动化 CI 中的代码资源注册
- 02向 ADF 作业传递准确资源版本
- 03排查私有存储访问故障
- 04在运行时验证 Azure ML 和 ADF 变更
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ josiahsiegel/ claude-plugin-marketplace --skill ml-azureml-adf-automation安装后在 Claude Code 中输入/ml-azureml-adf-automation确认已加载。
详细介绍
Azure ML 和 ADF 自动化
概述
当你需要在 CI 中注册代码资产,并通过 Azure Data Factory 编排训练、评分、注册或部署时,请使用此技能。核心不变原则是:运行时系统必须使用实际注册的 Azure ML 资产版本,而不是管道尝试请求的版本。请根据运行时行为验证每条建议,因为 Azure ML、ADF、存储网络和 SDK 依赖项行为可能与静态 API 文档不一致。
核心不变原则
- CI 负责注册 Azure ML 代码资产,并发布 SDK 实际返回的版本。
- ADF 通过明确的契约接收代码版本(通常是存储指针 Blob),而不是在运行时发现 AML 代码版本。
- SDK 结果是事实来源:请求的版本、构建 ID、分支名称或根据提交派生的字符串都不是权威信息。
- 私有存储不仅需要正确的 RBAC,还需要证明执行环境能够访问数据平面。
- 必须通过预期的集成运行时测试 ADF WebActivity 的网络连接,而不能只验证 JSON。
- Azure ML 自动化环境中的依赖项约束必须在 CI 中固定。
- 运行时证据优先于看似合理的 ARM 路径、文档片段或成功编译的模板。
Azure ML 代码资产注册
如果自动化需要可靠地获取已注册的版本,优先使用 Python SDK 注册 Azure ML 代码资产。只有在确认目标环境中的 az ml 扩展支持所需的代码命令,且返回的信息足以供下游自动化使用之后,才使用 Azure CLI。
from azure.ai.ml import MLClient
from azure.ai.ml.entities._assets._artifacts.code import Code
from azure.identity import AzureCliCredential
ml_client = MLClient(
AzureCliCredential(),
subscription_id,
resource_group,
workspace_name,
)
result = ml_client._code.create_or_update(
Code(name=code_name, version=requested_version, path=staged_code_path)
)
actual_version = result.version
print(actual_version)
不要假设 requested_version == result.version。Azure ML 代码资产可以根据内容哈希去重上传;如果暂存目录与先前的资产相同,就会返回已有版本。这种存储行为很有用,但如果 CI 发布的是请求的构建标识符,而不是 SDK 返回的版本,就会造成风险。
CI 输出变量模式
将返回的版本发布为管道输出变量,并将下游步骤连接到该输出。
print(
"##vso[task.setvariable "
f"variable=trainingCodeVersion;isOutput=true]{result.version}"
)
优先使用:
$registeredVersion = '$(RegisterTrainingCode.trainingCodeVersion)'
避免使用:
$registeredVersion = '$(Build.BuildId)'
如果即使代码内容重复,操作上仍要求资产版本唯一,请暂存代码目录,并在注册前写入一个小型标记文件,例如 .aml-code-asset-version。此方法仅用于解决去重问题。真正的契约仍然是 SDK 返回的 result.version。
ADF 到 Azure ML 的版本解析
除非经过运行时验证,否则不要让 ADF 通过 Azure ML ARM 代码容器端点发现 AML 代码版本。某些 AML 管理端点在 REST 文档中看似有效,但在执行时可能在 ADF WebActivity 中因不支持的操作而失败。在有证据证明并非如此之前,应将其视为服务行为,而不是主要归因于 RBAC 问题。
使用由 CI 写入的指针 Blob,作为注册与编排之间的运行时契约:
https://<storage-account>.blob.core.windows.net/ml-globals/code-assets/training-code/latest.json
示例负载:
{
"assetName": "training-code",
"version": "<actual-sdk-returned-version>",
"workspaceName": "<workspace-name>",
"resourceGroup": "<resource-group>",
"subscriptionId": "<subscription-id>",
"buildId": "<build-or-run-id>",
"sourceBranch": "<branch>",
"sourceVersion": "<source-version>",
"registeredAtUtc": "<timestamp>"
}
ADF 从此 Blob 中读取 version,并将其作为参数传递给训练、评分、模型注册或部署管道。负载可以包含来源信息字段,但下游作业只能依赖明确纳入契约的字段。
用于指针 Blob 读取的 ADF WebActivity
使用托管标识身份验证从 Azure Storage 读取指针 Blob:
{
"name": "ReadLatestTrainingCodeVersion",
"type": "WebActivity",
"typeProperties": {
"method": "GET",
"url": {
"type": "Expression",
"value": "@concat('https://', pipeline().globalParameters.StorageAccountName, '.blob.core.windows.net/ml-globals/code-assets/training-code/latest.json')"
},
"headers": {
"x-ms-version": "2023-11-03",
"Accept": "application/json"
},
"authentication": {
"type": "MSI",
"resource": "https://storage.azure.com/"
},
"connectVia": {
"referenceName": "<managed-vnet-ir-name>",
"type": "IntegrationRuntimeReference"
}
}
}
关键位置规则:对于 ADF WebActivity,connectVia 必须放在 typeProperties 内。如果将其放在活动根级别,可能会被忽略,导致流量经由公共互联网传出,并在 defaultAction: Deny 的存储帐户上失败。
通常需要以下访问权限:
- ADF 托管标识:在指针容器或帐户范围内拥有
Storage Blob Data Reader角色。 - CI 服务连接标识:拥有
Storage Blob Data Contributor角色,以写入指针 Blob。 - CI 服务连接标识:当流水线管理存储防火墙规则时,拥有
Storage Account Contributor角色。
私有存储和托管 CI Agent
对于具有专用终结点且 defaultAction: Deny 的存储帐户,Microsoft 托管 CI Agent 通常会使用每次运行分配的公共 IP 地址进行流出。如果 Agent 无法访问存储数据平面,仅有正确的 RBAC 权限并不足够。在归咎于 Azure ML SDK、ADF 或 IAM 之前,请先验证 Agent 是否能够访问存储。
安全的 CI 模式:
- 获取 Agent 的公共 IP。
- 为该 IP 添加临时存储网络规则。
- 等待规则传播。
- 对存储数据平面访问进行冒烟测试。
- 注册代码资源并写入指针 Blob。
- 在
always()清理步骤中移除临时规则。
$agentIp = (Invoke-RestMethod -Uri 'https://api.ipify.org' -TimeoutSec 20).Trim()
az storage account network-rule add `
--resource-group $rg `
--account-name $storageAccount `
--action Allow `
--ip-address $agentIp `
--only-show-errors
Start-Sleep -Seconds 30
az storage container list `
--account-name $storageAccount `
--auth-mode login `
--only-show-errors `
-o none
即使注册失败,也应执行清理。在 Azure DevOps YAML 中,应将网络规则移除操作放在带有 condition: always() 的步骤中。
Python 依赖项固定
某些版本的 azure-ai-ml 会导入 marshmallow 4.x 中不可用的私有 marshmallow 符号。托管 Agent 可能会安装不兼容的传递依赖版本,导致在任何 Azure ML API 调用运行之前就失败。使用受影响的版本时,请同时固定 SDK 和传递依赖。
python -m pip install --upgrade `
"azure-ai-ml==1.24.0" `
"azure-identity==1.19.0" `
"marshmallow>=3.18,<4.0"
如果使用较新的 SDK,请在 CI 中验证依赖行为,不要仅凭本地运行成功就移除版本固定。
ADF 开发工作流
确认哪种 ADF 执行模式会读取未发布的 Git 分支状态,哪种模式会运行已发布的工厂定义。调试运行可能会使用分支状态,而计划运行和生产运行通常会执行最近发布的工厂定义。手动触发的行为取决于工厂的配置和调用方式。请选择能够实际验证所做更改的模式。
运行时验证标准
应接受运行时证据,而非仅凭结构推断合理性。验证以下内容:
- Azure ML 注册返回了
result.version,且 CI 传递的正是该值。 - 指针 Blob 中包含 Azure ML 实际注册的版本。
- ADF 通过指定的集成运行时和托管标识读取 Blob。
- 使用实际的防火墙配置和 CI Agent 流出路径测试存储。
- 下游 ADF 参数会传递到运行时使用的 AML 作业定义中。
- AML 训练或评分作业使用预期的代码资源版本启动。
- SDK 导入在 CI 使用的同一托管 Agent 映像中成功。
以下验证方式并不足够:文档显示某个终结点存在、解析 JSON、看起来合理的 ARM URL、部署模板成功、日志中打印了请求的版本却未检查 result.version,或只有审查意见而没有运行时证据。
运维检查清单
- Azure ML 代码资产是否由 CI 负责注册?
- CI 是否捕获并发布 SDK 返回的
result.version? - ADF 是否通过显式参数或指针 Blob 获取准确的代码版本?
- 指针负载是否将契约字段与可选来源元数据分开?
- 在需要专用网络时,ADF WebActivities 是否在
typeProperties中使用connectVia? - MSI Blob 访问是否使用身份验证资源
https://storage.azure.com/? - ADF 托管标识是否具有
Storage Blob Data Reader权限? - CI 服务连接标识是否具有
Storage Blob Data Contributor权限? - 如果 CI 更改存储防火墙规则,是否会在清理过程中执行添加、等待、冒烟测试和移除?
- 是否固定了已知的 Azure ML SDK 依赖约束?
- 是否针对运行时基础设施路径进行了验证,而不只是编译或审查?
简要规则
- 注册代码时使用 Azure ML Python SDK,除非已在目标环境中验证 CLI 的行为。
- 切勿假设请求的版本等于已注册的版本。
- 将 SDK 的
result.version视为唯一可信来源。 - 未经运行时测试,不要从 ADF 中通过 AML ARM
/codes/...进行发现。 - 使用 Blob 指针作为 ADF 可读取的 ML 资产版本契约。
- 将 ADF WebActivity 的
connectVia放在typeProperties中。 - 假定托管 CI Agent 需要临时存储防火墙访问权限才能访问专用存储。
- 当 AML SDK 导入存在已知约束时,固定传递依赖。
- ML 基础设施变更必须经过运行时验证。
来源
- Azure Machine Learning 文档:https://learn.microsoft.com/azure/machine-learning/
- Azure Data Factory Web activity 文档:https://learn.microsoft.com/azure/data-factory/control-flow-web-activity
- Azure Storage 防火墙和虚拟网络文档:https://learn.microsoft.com/azure/storage/common/storage-network-security
- Azure Machine Learning Python SDK 文档:https://learn.microsoft.com/python/api/overview/azure/ai-ml-readme