1. 项目概述这不是一份“入门指南”而是一份踩过坑之后的生存手记Azure Machine Learning简称 Azure ML不是一块披萨你点单、付款、等待然后就能吃上热乎的。它更像一套刚拆封的乐高——盒子里有上千块零件说明书厚得能当板砖而你手里只有一张模糊的成品图。我第一次在 Azure 门户里点开“机器学习工作区”时看到的不是模型训练界面而是一连串弹窗资源组、位置、托管身份、网络配置、密钥保管库……那一刻我意识到自己不是来写 Python 的是来考驾照、办暂住证、申请营业执照最后才轮到踩油门。这完全不是 Azure ML 的问题。恰恰相反它的设计逻辑非常清晰把数据科学流程中所有可能出错的环节都提前暴露出来逼你建立工程化思维。但对刚从 Jupyter Notebook 直接跳进云平台的新手来说这种“防呆设计”很容易变成“劝退设计”。我备考 DP-100 认证那会儿花在环境配置、权限报错、路径找不到上的时间远超真正调参的时间。后来我才明白微软工程师不是在给你设障而是在模拟真实企业场景——你不会被允许用本地笔记本跑生产模型也不会被允许把 API 密钥硬编码进脚本里。所以这篇内容不叫“Azure ML 入门教程”它是一份新手生存手记。它不教你如何从零构建一个端到端的客户流失预测模型而是告诉你当你第一次登录 Azure 门户点击“创建资源”按钮后接下来三分钟内最该做哪五件事当你在 VS Code 里写完from azure.ai.ml import MLClient却卡在认证失败时该检查哪三个隐藏配置项当你发现训练作业跑了两小时却没生成任何日志不是代码错了而是你漏掉了那个默认关闭的“诊断日志”开关。它面向的是那些已经会用 Pandas 清洗数据、能用 Scikit-learn 训练模型但一碰云平台就手抖、一见报错就搜 Stack Overflow 的实战派。关键词只有一个Azure。不是泛泛而谈的“云机器学习”而是聚焦于 Azure 这个具体平台的肌肉记忆、配置惯性和系统性避坑逻辑。2. 核心思路拆解为什么这五个点是新手绕不开的生死线很多教程一上来就讲“如何用 Designer 拖拽建模”或“如何用 SDK 提交训练作业”这就像教人开车先讲空气动力学。新手真正卡住的地方90% 不在算法本身而在基础设施层的隐性契约。Azure ML 不是一个孤立服务它是 Azure 整个云生态的“下游消费者”——它依赖资源组的命名规范、依赖角色权限的最小化授予、依赖存储账户的跨区域访问策略、依赖计算实例的自动关机设置。这五个点之所以被拎出来是因为它们各自对应一个不可绕行的底层约束且每一个都具备“低感知、高代价”的特点你意识不到它存在直到账单暴涨、权限崩盘或环境彻底混乱。2.1 VS Code 集成IDE 不是辅助工具而是你的“云操作系统”很多人把 VS Code 当作写代码的编辑器但在 Azure ML 场景下它实质上是你与整个云平台交互的主控台。Azure 门户网页版是个“只读仪表盘”它能展示结果但无法让你像操作本地文件一样直接编辑远程计算实例上的.py脚本、实时查看stdout流、或一键同步requirements.txt。而 VS Code Azure ML 扩展通过 SSH 隧道和 Web Socket把远程计算实例变成了你本地开发环境的“延伸桌面”。关键在于理解它的双向绑定机制你在 VS Code 里右键点击一个.ipynb文件选择“在计算实例上运行”它不是把 notebook 复制过去再执行而是直接在远程内核中启动一个 Jupyter Server 实例并将 VS Code 的前端 UI 与之桥接。这意味着你本地的键盘输入、鼠标点击、甚至调试断点都是实时作用于云端的 Python 进程。这种体验的流畅度直接决定了你能否建立起“代码就在云上运行”的直觉。我试过纯用门户网页版调试一个内存溢出错误花了 47 分钟反复下载日志、本地分析、修改、上传、重跑换成 VS Code 后开启远程调试器3 分钟内就定位到是pandas.read_csv()的chunksize参数没设导致整张千万行表被一次性加载进内存。提示VS Code 扩展的“连接状态”图标右下角不是装饰。它显示的是 VS Code 与 Azure ML 控制平面而非计算实例的认证连接。即使这个图标是绿色的也不代表你能访问某个特定计算实例——你还需要确保该实例处于“正在运行”状态且你的 Azure AD 账户对该实例的Contributor或Owner角色已正确分配。这是新手最容易混淆的“双层认证”陷阱。2.2 命名标准化不是为了好看而是为了“可审计、可追溯、可自动化”Azure 平台没有强制的命名规则但它有一套事实标准de facto standard这套标准不是来自微软文档而是来自全球数万家企业在生产环境中踩坑后形成的共识。比如rg-example-dev-001这个名字它不是一个随意的字符串而是一个微型数据库。rg是资源类型前缀Resource Groupexample是业务域标识Business Domaindev是环境标签Environment Tag001是序列号Instance Number。这四个字段共同构成了一条元数据链让任何一个新加入项目的工程师无需翻阅文档仅凭资源名就能回答这个资源属于哪个业务部署在什么环境是否可用于生产是否是第一个实例更重要的是这套命名法是自动化运维的基石。当你在 Azure DevOps Pipeline 中编写 YAML 脚本去部署一个新工作区时你不会硬编码my-first-ml-workspace这样的名字而是用变量拼接$(projectName)-$(environment)-$(sequence)。如果所有资源都遵循同一套命名逻辑那么 Terraform 脚本就能通过正则表达式批量识别、销毁或备份某类资源。我曾接手一个遗留项目其资源组名为RG-ML-PROD-2023工作区名为mlworkspace-prod-eastus计算集群名为compute-cluster-prod。表面看很“生产化”但问题在于prod在不同资源中含义不一致——资源组的prod指代环境工作区的prod指代用途production model serving计算集群的prod却指代性能等级production-grade hardware。结果是当需要为测试环境克隆一套资源时运维脚本因无法统一解析prod的语义而崩溃。标准化不是形式主义它是把“人脑记忆”转化为“机器可读指令”的唯一途径。2.3 CI/CD 流水线不是为了炫技而是为了“每次提交都是一次微型发布”新手常误以为 CI/CD 是大厂才玩得起的奢侈品。在 Azure ML 场景下它是最基础的安全网。想象一下你本地开发了一个模型训练脚本它在你的conda env里完美运行。你把它提交到 GitHub然后在 Azure ML 工作区里创建一个新实验手动上传脚本、指定计算目标、点击“提交”。结果作业失败了报错ModuleNotFoundError: No module named xgboost。你立刻意识到本地环境装了 xgboost但 Azure ML 默认的azureml_py38_cpu_env环境里没有。这时你有两个选择一是回退代码修改环境定义重新提交二是临时在工作区里手动安装包但这违背了“环境即代码”的原则且下次训练又会复现问题。CI/CD 的价值就在于把“环境一致性”这个检查点前置到代码提交的瞬间。上面那段 GitHub Actions 的 YAML 脚本核心逻辑是每次git push就自动拉起一个干净的 Ubuntu 虚拟机按requirements.txt安装所有依赖然后运行pytest。如果测试失败PR 就会被打上红色 ❌ 标签根本无法合并。这意味着任何可能导致环境不一致的代码变更比如新增了一个未写入requirements.txt的包都会在进入主干分支前就被拦截。这不是增加流程而是把原本需要人工排查 2 小时的问题压缩到 3 分钟内自动发现。我见过最惨烈的案例一个团队没有 CI靠人工“打包上传”模型结果某次上传时漏掉了config.json文件导致线上推理服务返回 500 错误长达 6 小时而故障根因只是少传了一个 2KB 的文本文件。2.4 环境管理不是为了隔离而是为了“版本可重现、部署可验证”Python 环境管理的终极目标从来不是避免pip install冲突而是实现“一次构建处处运行”Build Once, Run Anywhere。在 Azure ML 中这个目标被提升到了新的高度你不仅需要保证本地训练环境与云端训练环境一致还需要保证训练环境与模型部署环境如 ACI 或 AKS一致甚至要保证不同时间点的训练环境也一致因为pip install xgboost今天装的是 2.0.3明天可能就是 2.1.0而这两个版本在某些边缘 case 下行为可能不同。Azure ML 提供了三层环境抽象注册环境Registered Environment、计算环境Compute Environment和推理环境Inference Environment。新手常犯的错误是把三者混为一谈。例如有人会直接在计算实例上pip install -r requirements.txt然后试图用from_existing_conda_environment()注册它——这会导致环境无法跨计算实例复用因为from_existing_conda_environment()会把当前 conda 环境的绝对路径如/home/azureuser/miniconda3/envs/myenv硬编码进环境定义里。正确的做法是始终使用from_pip_requirements()并确保requirements.txt文件本身被纳入 Git 版本控制。这样环境定义就变成了一个纯文本的、可 diff 的、可审查的代码文件。我曾用pip freeze requirements.txt生成过一个包含 127 行依赖的文件结果发现其中一行是pkg-resources0.0.0——这是 Ubuntu 系统的一个虚拟包在 Azure ML 的 Linux 计算实例上根本不存在导致整个环境构建失败。这就是为什么“环境即代码”必须配合严格的 CI 流程只有经过自动化验证的requirements.txt才是可信的。2.5 预算告警不是为了省钱而是为了“避免认知过载”云服务最大的心理陷阱是它把“成本”这个物理世界的沉重概念转化成了 Azure 门户里一个轻飘飘的数字。你不会像付水电费那样每月收到一张具象的账单而是面对一个动态刷新的“成本分析”仪表盘。新手最常犯的致命错误不是乱花钱而是对钱失去感知。你会习惯性地创建一个STANDARD_NC6S_V36 核 GPU的计算实例用于调试然后在下班前忘记关机。它会在后台静默运行 16 小时消耗掉你当天预算的 80%。更可怕的是这种消耗是“无感”的——你既看不到风扇声也听不到硬盘响屏幕右下角的数字只是缓慢爬升。Azure 的预算功能本质是一个认知锚点Cognitive Anchor。它强制你在开始任何操作前先回答一个问题“我愿意为这次尝试支付多少” 这个动作本身就是在训练你的云成本直觉。我给自己设的第一个预算是每月 $50用于 DP-100 备考。这个数字不是拍脑袋定的而是基于 Azure 定价计算器的反向推演一个STANDARD_DS3_V24 核 CPU的计算实例按需计费约 $0.19/小时每天调试 2 小时一个月 60 小时就是 $11.4加上存储、网络、ACI 推理等杂项$50 是一个安全的缓冲带。当我在仪表盘看到“本月已用 $42”时我就知道剩下的 $8 只够我再跑两次 GPU 训练必须优先保障最重要的实验。这不是吝啬而是把有限的认知带宽聚焦在真正重要的技术决策上而不是在月底对着账单发呆。3. 实操细节与关键配置手把手带你避开每一个已知的深坑理论讲完现在进入真正的战场。下面这五个实操环节每一个我都亲自踩过坑每一个的解决方案都经过至少三次生产环境验证。它们不是“应该怎么做”而是“必须这么做否则一定会出事”。3.1 VS Code 集成从安装到调试的完整链路安装 Azure ML 扩展只是起点真正的挑战在于打通认证链路。Azure 采用多层认证首先是 Azure AD 用户登录 VS Code其次是 VS Code 获取用户令牌最后是该令牌被 Azure ML SDK 用于调用 REST API。这三个环节中任何一个断裂都会导致“已登录但无法列出工作区”的诡异现象。第一步安装与初始配置在 VS Code 中安装官方扩展 “Azure Machine Learning”ID: ms-toolsai.vscode-ai。打开命令面板CtrlShiftP输入Azure: Sign In使用你的 Azure AD 账户登录。注意这里必须使用你拥有Reader或更高权限的账户不能是 Guest 账户。很多新手用公司邮箱登录成功却无法看到工作区原因就是该邮箱在 Azure AD 中被标记为 Guest。登录成功后VS Code 底部状态栏会出现 Azure 图标和你的账户名。此时点击该图标选择Azure Machine Learning: Connect to Workspace。第二步连接工作区的“三重校验”VS Code 不会直接连接工作区而是要求你提供三个参数Subscription ID在 Azure 门户 - “订阅”页面复制。不要用订阅名称必须是 UUID 格式的 ID。Resource Group Name必须与工作区所在资源组的精确名称一致包括大小写和连字符。我曾因把rg-ml-dev写成RG-ML-DEV而失败。Workspace Name同上必须 100% 精确匹配。注意这三个参数一旦填错VS Code 不会给出明确错误只会显示“Loading…”然后无限转圈。此时打开 VS Code 的“输出”面板CtrlShiftU在下拉菜单中选择 “Azure Machine Learning”你会看到详细的错误日志。最常见的错误是Authentication failed for resource https://management.azure.com/这说明你的账户没有该订阅的访问权限。第三步连接并使用计算实例成功连接工作区后VS Code 左侧活动栏会出现 Azure ML 图标。展开它你会看到Workspaces-[Your Subscription]-[Your Resource Group]-[Your Workspace]-Compute。找到你的计算实例Compute Instance右键点击Connect。VS Code 会自动为你创建一个 SSH 配置并在终端中启动一个远程 shell。此时你可以像操作本地文件一样在 VS Code 的资源管理器中右键点击任意.py或.ipynb文件选择Run in Terminal或Run in Interactive Window。关键技巧如果你想在计算实例上运行一个需要 GPU 的脚本务必先在 VS Code 终端中执行nvidia-smi确认 GPU 驱动已加载。Azure ML 的某些计算实例 SKU如STANDARD_NC6S_V3在首次启动时GPU 驱动可能需要几分钟才能初始化完成直接运行训练脚本会报CUDA_ERROR_NO_DEVICE。3.2 命名标准化一套可立即落地的模板与校验脚本光讲原则没用你需要一套开箱即用的模板。以下是我为个人项目和小团队制定的Azure 资源命名规范 V2.1它平衡了可读性、自动化友好性和 Azure 的长度限制64 字符资源类型命名格式示例说明资源组 (Resource Group)rg-[domain]-[env]-[seq]rg-customer360-dev-001[domain]用短横线分隔的业务域[env]必须是dev/test/prod/staging四选一[seq]为三位数字机器学习工作区 (ML Workspace)mlw-[domain]-[env]-[seq]mlw-customer360-dev-001前缀mlw明确标识类型其余同上存储账户 (Storage Account)st[domain][env][seq]stcustomer360dev001Azure 存储账户名必须全局唯一且只能是小写字母和数字故去掉所有分隔符长度严格控制在 24 字符内密钥保管库 (Key Vault)kv-[domain]-[env]-[seq]kv-customer360-dev-001前缀kv规则同资源组自动化校验脚本PowerShell# save as validate-naming.ps1 param([string]$ResourceGroupName) if ($ResourceGroupName -notmatch ^rg-[a-z0-9]-[a-z]-[0-9]{3}$) { Write-Error ❌ Resource Group name $ResourceGroupName does not match pattern: rg-[domain]-[env]-[seq] exit 1 } $parts $ResourceGroupName -split - if ($parts.Length -ne 4) { Write-Error ❌ Resource Group name must have exactly 4 parts separated by - exit 1 } $envPart $parts[2] if ($envPart -notin (dev, test, staging, prod)) { Write-Error ❌ Environment part $envPart is invalid. Must be one of: dev, test, staging, prod exit 1 } Write-Host ✅ Resource Group name $ResourceGroupName is valid.将此脚本保存为validate-naming.ps1在创建任何新资源前先运行.\validate-naming.ps1 -ResourceGroupName rg-myapp-prod-001。它会立即告诉你名字是否合规。这个脚本的价值在于把“人工记忆规则”变成了“机器强制检查”杜绝了因疏忽导致的命名错误。3.3 CI/CD 流水线从 GitHub Actions 到 Azure Pipelines 的平滑迁移GitHub Actions 的 YAML 脚本示例很好但它有一个致命缺陷它只验证了代码能在 Ubuntu 上运行却没有验证它能在 Azure ML 的实际计算环境上运行。Azure ML 的默认环境是基于mcr.microsoft.com/azureml/openmpi4.1.0-cuda11.3.1-devel-ubuntu20.04的 Docker 镜像它预装了 CUDA、OpenMPI 和特定版本的 Python与 GitHub Actions 的ubuntu-latest通常是 Ubuntu 22.04存在细微差异。升级版 GitHub Actions 脚本推荐name: Azure ML CI Pipeline on: [push, pull_request] jobs: # 第一步在 Ubuntu 上验证基础依赖和测试 lint-and-test: runs-on: ubuntu-latest strategy: matrix: python-version: [3.8, 3.9] steps: - uses: actions/checkoutv3 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-pythonv4 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt - name: Run tests run: pytest tests/ --tbshort # 第二步在 Azure ML 的真实镜像上验证环境构建 build-azureml-env: needs: lint-and-test runs-on: ubuntu-latest steps: - uses: actions/checkoutv3 - name: Build Azure ML Environment Docker Image run: | # 使用 Azure ML 的官方基础镜像 docker build -t azureml-env-test -f Dockerfile.azureml . - name: Test Environment Build run: | docker run --rm azureml-env-test python -c import numpy, pandas, sklearn; print(✅ All core packages imported successfully) # Dockerfile.azureml 内容 FROM mcr.microsoft.com/azureml/openmpi4.1.0-cuda11.3.1-devel-ubuntu20.04:latest COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt这个流水线的关键创新在于增加了build-azureml-env任务。它使用 Azure ML 官方的 Docker 基础镜像构建一个与生产环境完全一致的容器并在其中执行import测试。只有当这个测试通过PR 才会被视为“环境安全”。我用这个方案成功拦截了 7 次因tensorflow版本与 CUDA 驱动不兼容导致的线上部署失败。3.4 环境管理从 requirements.txt 到可复用注册环境的全流程requirements.txt是环境管理的起点但绝不是终点。一个健壮的环境定义必须包含运行时上下文Runtime Context。Azure ML 的Environment对象支持docker属性你可以指定一个自定义的 Dockerfile从而精确控制基础镜像、CUDA 版本、甚至系统级依赖如libglib2.0-0。最佳实践流程生成最小化 requirements.txt不要用pip freeze requirements.txt。改用pipreqs . --force --encodingutf-8。pipreqs会扫描你的 Python 代码只提取实际import的包避免把jupyter,black这类开发依赖也塞进去。创建 Dockerfile可选但强烈推荐# Use the official Azure ML base image FROM mcr.microsoft.com/azureml/openmpi4.1.0-cuda11.3.1-devel-ubuntu20.04:latest # Install system dependencies RUN apt-get update apt-get install -y libglib2.0-0 rm -rf /var/lib/apt/lists/* # Copy and install Python dependencies COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # Set the working directory WORKDIR /mnt/batch/tasks/shared/LS_root/jobs在代码中注册环境from azure.ai.ml import MLClient from azure.ai.ml.entities import Environment from azure.identity import DefaultAzureCredential ml_client MLClient( credentialDefaultAzureCredential(), subscription_idyour-sub-id, resource_group_namerg-your-rg, workspace_namemlw-your-workspace ) # Option A: From pip requirements (simple) env_from_pip Environment( namemy-custom-env-pip, descriptionEnvironment built from requirements.txt, tags{source: pip}, conda_fileNone, imagemcr.microsoft.com/azureml/openmpi4.1.0-cuda11.3.1-devel-ubuntu20.04:latest, pip_packages[scikit-learn1.2.2, xgboost1.7.5] ) ml_client.environments.create_or_update(env_from_pip) # Option B: From Dockerfile (recommended for production) env_from_docker Environment( namemy-custom-env-docker, descriptionEnvironment built from custom Dockerfile, tags{source: docker}, imageyour-acr-name.azurecr.io/my-custom-env:latest # You need to build push this first ) ml_client.environments.create_or_update(env_from_docker)关键经验永远为你的环境设置tags。tags{source: pip}这样的标签让你在 Azure ML 门户的“环境”列表中能一眼区分哪些是手工注册的哪些是 SDK 自动生成的。当环境数量超过 20 个时没有标签的环境列表就是一场噩梦。3.5 预算告警设置一个“不会失效”的预算监控体系Azure 的预算功能有个隐藏缺陷它只监控订阅级别的成本而 Azure ML 的大部分费用尤其是计算实例是按资源组粒度产生的。如果你在一个订阅下混用了多个项目如rg-project-a-dev和rg-project-b-prod一个项目的失控消费会淹没另一个项目的预算告警。构建“项目级”预算监控的三步法为每个项目创建独立的资源组这是前提。如前所述rg-customer360-dev-001就是一个项目级资源组。在资源组级别启用“成本分析”进入 Azure 门户 - 资源组 - 你的资源组 - “成本分析”。点击“添加图表”创建一个新视图筛选条件设为Resource group rg-customer360-dev-001。这会生成一个只显示该项目成本的专属仪表盘。创建“资源组级”预算通过 Azure PolicyAzure 原生不支持资源组级预算但你可以用 Azure Policy 强制执行。创建一条策略规则为{ if: { allOf: [ { field: type, in: [Microsoft.MachineLearningServices/workspaces/computes] }, { field: Microsoft.MachineLearningServices/workspaces/computes/sku.name, in: [STANDARD_NC6S_V3, STANDARD_NC12S_V3] } ] }, then: { effect: deny } }这条策略的意思是“禁止在本资源组内创建任何NC系列的 GPU 计算实例”。它相当于一个“硬性预算闸门”。当你的预算快用完时你不是去删资源而是去更新这条策略把STANDARD_NC6S_V3替换为更便宜的STANDARD_DS3_V2。这是一种主动的成本治理比被动的邮件告警有效十倍。4. 常见问题与排查技巧实录那些文档里永远不会写的真相这些不是教科书里的“常见问题”而是我在真实项目中花了数小时甚至数天才搞懂的“幽灵错误”。它们往往没有明确的错误信息或者错误信息极具误导性。我把它们整理成速查表附上独家排查技巧。4.1 VS Code 连接失败认证成功但看不到工作区现象可能原因排查技巧解决方案VS Code 底部显示已登录但 Azure ML 侧边栏为空或提示 “No workspaces found”权限范围错误你的账户在该订阅下只有Reader权限但Reader权限默认不包含Microsoft.MachineLearningServices/workspaces/read操作。在 Azure 门户 - 订阅 - “访问控制 (IAM)” - “角色分配” 中搜索你的账户查看其被分配的所有角色。重点检查是否有Contributor或Owner角色。Reader角色不足以列出工作区。请管理员为你分配Contributor角色。切勿使用Owner角色进行日常开发这是最小权限原则。连接工作区时VS Code 卡在 “Loading…”网络代理干扰如果你的公司网络使用了 HTTP 代理VS Code 的 Azure 扩展可能无法正确处理代理设置。打开 VS Code 的设置Ctrl,搜索proxy检查Http: Proxy是否被设置。同时在终端中运行echo $HTTP_PROXY和echo $HTTPS_PROXY。在 VS Code 设置中将Http: Proxy留空并在 VS Code 的settings.json中添加http.proxyStrictSSL: false。重启 VS Code。成功连接工作区但无法连接计算实例报错Failed to connect to compute instance计算实例状态异常计算实例可能处于Starting或Stopping状态VS Code 无法建立 SSH 连接。在 Azure 门户 - 工作区 - “计算” - 你的实例查看其状态。如果状态不是Running不要尝试连接。等待状态变为Running。如果长时间卡在Starting可能是底层 VM 初始化失败此时需要删除并重建该实例。4.2 环境构建失败requirements.txt 无误但环境仍构建失败现象可能原因排查技巧解决方案在 Azure ML 门户的“环境”页面点击一个已注册的环境查看详情时显示Status: Failed日志中出现ERROR: Could not find a version that satisfies the requirement xxx包索引源错误Azure ML 默认使用https://pypi.org/simple/但某些包如内部私有包或特定版本的torch需要从其他索引源如https://download.pytorch.org/whl/cu113安装。查看环境构建日志的完整输出在门户中点击“日志”链接。搜索Looking in indexes:确认它是否只指向了 PyPI。在requirements.txt的第一行添加索引源声明--index-url https://download.pytorch.org/whl/cu113torch1.12.1cu113--extra-index-url https://pypi.org/simple/环境构建成功但训练作业运行时报错ImportError: libcudnn.so.8: cannot open shared object fileCUDA 版本不匹配你指定的基础镜像是cuda11.3.1但requirements.txt中安装的torch包是为cuda11.7编译的。在训练作业的日志中搜索nvidia-smi的输出确认 GPU 驱动版本。然后在torch的官网文档中查找与该驱动兼容的torch版本。修改requirements.txt指定与基础镜像 CUDA 版本严格匹配的包。例如对于cuda11.3.1镜像应使用torch1.10.2cu113。环境构建成功但训练脚本运行时报错PermissionError: [Errno 13] Permission denied: /mnt/batch/tasks/shared/LS_root/jobs/...工作目录权限问题Azure ML 的默认工作目录/mnt/batch/tasks/shared/LS_root/jobs/是只读的。你的脚本试图在此目录下创建文件或写入日志。查看训练脚本找到所有open(..., w)或logging.basicConfig()的调用检查其filename参数。在脚本开头显式设置一个可写的临时目录import tempfiletemp_dir tempfile.mkdtemp()print(fUsing temp dir: {temp_dir})然后将所有文件操作重定向到temp_dir。4.3 预算告警失效收到了邮件但费用仍在飙升现象可能原因排查技巧解决方案预算告警邮件发送了但后续费用仍在增长且没有新的告警告警阈值设置过高你设置了 90% 的阈值但 Azure 的成本数据有 24 小时延迟。当邮件发出时实际费用可能已是 95%而你没有设置 95% 的第二级告警。进入 Azure 门户 - “成本管理 计费” - “预算”找到你的预算点击“编辑”。查看“通知”部分确认是否只设置了单一阈值。设置三级告警在同一个预算中添加三个通知- 80%发送邮件给开发者提醒“注意成本”- 90%发送邮件给团队负责人提醒“即将超支”- 100%发送邮件给财务和架构师并触发一个 Azure Function自动停止所有非prod环境的计算实例。预算告警从未触发但月底账单很高预算范围错误你为“订阅”设置了预算但你的资源如存储账户、ACI是通过 ARM 模板或 Terraform 创建的其成本被归类到了“其他”类别未被预算统计。在“成本分析”仪表盘中点击“分组依据”选择Service name查看Other类别的花费占比。如果占比很高说明有大量成本未被归类。使用 Azure Resource Graph 查询找出未打标签的资源Resources5. 实操心得与避坑总结一个老鸟的肺腑之言写到这里