所有博客
成本优化竞价实例微调

竞价实例训练指南:用几折价格跑完大模型微调

竞价实例价格通常只有按量计费的 3-5 折,但随时可能被回收。这篇文章教你如何安全地用竞价实例跑训练:高频 checkpoint、监听中断信号、选对任务类型。

RRunWhere Team·2025年5月18日·7 分钟阅读
竞价实例训练指南:用几折价格跑完大模型微调

竞价实例(Spot Instance)是各大云厂商提供的低价 GPU 资源:你以远低于按量计费的价格使用闲置 GPU,代价是云厂商有权在需要时回收这台机器。折扣力度通常在按量价的 3-5 折区间,具体随供需实时波动。

听起来很不靠谱?但如果训练流程做好了中断容错,竞价实例能帮你把同样的预算跑出 2-3 倍的实验量。

先看实时价格,别拍脑袋

竞价折扣不是固定值,不同云、不同区域、不同时段差异很大。在 RunWhere 上,你可以直接在控制台的「价格」页按计费模式筛选竞价机型,对比各家的实时报价;或者用 CLI:

runw price recommend -f train.yaml --top 3

选中报价后把 gpuSkuKey 写回 YAML,价格就锁定了,不会提交时才发现换了价。

核心风险:随时可能被中断

云厂商回收实例前会给出短暂的通知窗口,然后强制回收。如果训练没有 checkpoint,中断就意味着从头再来。所以用竞价实例的前提只有一个:你的训练必须可恢复

安全使用竞价实例的 3 个关键

1. 高频 Checkpoint

每 10-15 分钟保存一次,而不是每个 epoch。中断后最多丢失十几分钟的计算量:

save_interval = 900  # 每 900 秒保存一次
last_save = time.time()

for step, batch in enumerate(dataloader):
    loss = train_step(model, batch)

    if time.time() - last_save > save_interval:
        save_checkpoint(model, optimizer, step)
        last_save = time.time()

在 RunWhere 上,checkpoint 的存放位置在 YAML 的 storage.checkpoint 里声明,直接落在你自己云账号的存储里——实例被回收也不丢。更完整的写法见文档站的 checkpoint 最佳实践

2. 监听中断信号

收到回收通知后,在强制关机前保存当前状态:

import signal
import sys

def handle_preemption(signum, frame):
    print("收到中断信号,正在保存 checkpoint...")
    save_checkpoint(model, optimizer, current_step)
    sys.exit(0)

signal.signal(signal.SIGTERM, handle_preemption)

3. 训练脚本启动时自动恢复

脚本开头检测最新 checkpoint,存在就接着练,这样无论在新实例上重启多少次,进度都在:

latest = find_latest_checkpoint(checkpoint_dir)
if latest:
    checkpoint = torch.load(latest)
    model.load_state_dict(checkpoint["model_state"])
    start_epoch = checkpoint["epoch"] + 1

什么任务适合竞价实例

  • LoRA / QLoRA 微调(通常几小时内,checkpoint 恢复快)
  • 超参搜索(本身就是多次独立实验,中断一个不影响其他)
  • 数据预处理和特征工程(无状态,重跑成本低)

什么任务不适合

  • 多节点分布式训练(中断一个节点拖累所有节点)
  • 训练时间很短的任务(省不了多少钱,还增加复杂度)
  • 对可用性敏感的推理服务(中断 = 服务中断)

一句话总结:竞价实例省钱的前提是可恢复的训练流程。checkpoint 做扎实了,竞价就是纯粹的折扣;做不扎实,省下的钱迟早以重跑的方式还回去。

想体验 RunWhere.ai?

Free 永久免费,自带云账号,无需信用卡,30 秒启动第一个 GPU 任务。

免费开始 →