You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure虚拟机规模集:可靠分配、运行程序与释放方案问询

批量运行计算密集型模型的云环境问题

需求背景

需要批量运行多个计算密集型模型,目标是创建100台虚拟机,运行指定模型后关闭。由于每次运行的模型不同,不希望虚拟机开机自动运行程序,而是由外部指定要运行的程序。

当前方案

计划使用Azure文件共享(Azure fileshare)和Azure虚拟机规模集(VM Scale Set):已编译为EXE的各类程序、模型数据与输出文件都存储在文件共享中。全程通过.NET(F#代码)控制流程,不使用PowerShell或Azure门户,方便其他工具自动触发虚拟机操作。

尝试通过Azure.ResourceManager API实现以下流程:

  1. 启动虚拟机
  2. 通过RunCommand执行脚本,映射文件共享至驱动器并启动目标EXE
  3. 关闭并释放虚拟机

遇到的问题

方案可运行但可靠性极低:

  • 调度不稳定:从所有VMSS实例处于Deallocated状态启动时,多数实例成功启动,但有相当数量的实例长时间卡在“Updating (Running)”状态(30分钟内未完成),严重影响运行效率。
  • 状态留存异常:成功启动的虚拟机似乎会自动运行之前的脚本(可看到模型输出),但代码逻辑是等所有虚拟机启动后才会尝试执行脚本。看起来虚拟机在关机并释放后,仍会保留之前的脚本状态,原本以为分配后会从初始镜像全新启动。

核心问题

  1. 是否存在可靠的虚拟机分配、运行程序与释放的实现方式?
  2. 虚拟机分配/开机后的状态是“全新状态”,还是会保留释放前的状态?
  3. 考虑过其他方案(如Azure Batch),但希望尽可能简化,因Azure文档较难理解,当前方案看似复杂度最低。

控制程序代码示例

let vmss = resourceGroup.GetVirtualMachineScaleSet("myScaleSet").Value
let powerOn = vmss.PowerOn(Azure.WaitUntil.Completed)
let vms =
    vmss.GetVirtualMachineScaleSetVms()
    |> Seq.cast<VirtualMachineScaleSetVmResource>
    |> List.ofSeq
let scripts =
    vms
    |> List.map (fun vm ->
        let name = vm.Id.Name
        let command = Models.RunCommandInput("RunPowerShellScript")
 
        command.Script.Add(@"net use S: /delete")
        command.Script.Add(@"Net use S: \fileshare etc.")
        command.Script.Add(@"& S:\MyModel.exe "+name)

        Console.WriteLine("    "+vm.Id.Name+" starting script")
        vm.RunCommand(Azure.WaitUntil.Started, command)
    )

Console.Write("Waiting for scripts to complete... ")
let results = scripts |> List.map (fun op -> op.WaitForCompletionResponse())

// Some code to check for when the model has run

let powerOff =
    vms
    |> List.map (fun vm ->
        let data = vm.Data
        Console.WriteLine("    "+vm.Id.Name+" powering off")
        vm.PowerOff(Azure.WaitUntil.Started)
    )
Console.Write("Waiting for power off... ")
powerOff |> List.iter (fun op -> op.WaitForCompletionResponse() |> ignore)
Console.WriteLine("completed")

Console.Write("Deallocating VMs... ")

vmss.Deallocate(Azure.WaitUntil.Completed) |> ignore

问题解答

1. 虚拟机分配/开机后的状态说明

虚拟机从Deallocated状态启动时,默认会保留上次释放前的磁盘状态(包括系统盘和数据盘),不会从初始镜像全新启动。只有执行**重新部署(Redeploy)**操作,或者在VMSS配置中结合overprovision与deleteVMOnScaleDown实例删除策略,才会得到近似“全新状态”的实例。你遇到的脚本自动运行问题,大概率是系统盘保留了上次运行的脚本残留(比如RunCommand历史执行记录被误触发,或脚本在系统中留下开机自启配置)。

2. 可靠的虚拟机分配、运行与释放实现方式

针对你的场景,优化现有VMSS方案可提升可靠性,具体调整如下:

  • 分批启动实例:一次性启动100台会触发Azure调度限流,导致部分实例卡顿。建议分批次启动(如每批20台),每批启动完成后再执行RunCommand,避免资源竞争。
  • 用Redeploy替代简单PowerOn:启动前对Deallocated状态的实例执行Redeploy,强制Azure将实例迁移到新宿主机并从镜像重新初始化系统盘,确保实例处于干净状态。
  • 优化RunCommand脚本:
    • 避免用net use映射驱动器,改用UNC路径直接访问文件共享(\\fileshare\path\MyModel.exe),减少驱动器冲突。
    • 脚本开头添加状态重置逻辑,比如删除上次运行的输出文件,避免残留干扰。
    • 使用Start-Process -Wait确保EXE执行完成后再退出脚本,避免RunCommand提前结束导致流程误判。
  • 完善状态检查逻辑:不要仅依赖VM的“Running”状态,需确认实例ProvisioningState为Succeeded且PowerState为VM running后,再执行脚本。
  • 调整释放顺序:先确保所有EXE执行完成,再逐个关闭实例,最后执行VMSS的Deallocate操作,避免批量操作导致任务未完成就终止。

3. 关于Azure Batch的简化方案

如果希望进一步简化流程,Azure Batch更适合批量计算场景:

  • Batch会自动管理虚拟机的创建、调度、运行和销毁,无需手动处理VMSS的启动/释放逻辑。
  • 可直接将任务提交到Batch池,系统自动分发任务到空闲节点,任务完成后可自动缩放池大小(甚至缩至0)。
  • 支持通过.NET SDK(包括F#)完全控制流程,无需手动编写RunCommand脚本,只需指定任务的执行命令和资源文件位置。
  • 虽然文档看似复杂,但针对你的场景,只需创建Batch池(配置虚拟机规格和数量)并提交任务(指定EXE和参数)即可实现自动化,长期来看比VMSS方案更可靠、维护成本更低。

内容的提问来源于stack exchange,提问作者Paul Whiting

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 13:38:18