Accelerate恢复训练时如何保存随机数状态
Accelerate恢复训练时,应使用accelerator.save_state()保存断点,再在同一训练脚本、相同对象准备完成后调用accelerator.load_state()。这组接口包含训练所需的随机数状态;只保存模型参数或重新执行set_seed,不能替代完整训练断点。
官方文档入口:https://huggingface.co/docs/accelerate/index
设想一个训练任务需要让操作者选择“从头开始”或“继续上次训练”。对操作者而言,继续应当对应一个明确断点,而不是重新走一遍随机序列。下面以完整epoch结束处保存为例,把这个选择落实到代码。示例限定单进程CPU、顺序读取的固定数据、无多worker增强和无梯度累积;它是未执行的教学代码,不是已经完成的训练实验。
为什么相同seed不等于恢复到暂停位置
seed决定随机序列的起点,状态则描述随机数发生器当前的位置。模型初始化、Dropout和随机增强都可能消耗随机数。训练已经进行一段时间之后重新设同一个seed,相当于把发生器放回起点,而不是放到断点处。
因此,“从头开始”可以使用固定seed建立初始条件;“继续训练”则需要恢复保存的状态。恢复后不要再调用set_seed,也不要为了打印调试样本先抽一批随机数,否则训练开始前就改变了该状态。
save_state负责什么,业务代码还负责什么
官方checkpoint指南将模型、优化器、随机数发生器和混合精度缩放器视为训练状态。自定义对象需要提供state_dict和load_state_dict并登记。恢复对象的结构及登记方式应与保存时一致,不能把目录中的任意文件都当成自动加载的内容。
| 对象 | 处理方式 | 易混淆之处 |
|---|---|---|
| 模型与优化器 | prepare后由训练状态接口管理 | 仅模型权重不含优化器历史 |
| 全局随机数状态 | 随save_state保存,load_state恢复 | 不是只保存一个seed数值 |
| 业务epoch计数 | 封装并register_for_checkpointing | 普通Python变量不会自动登记 |
| 自建生成器 | 明确保存自身状态 | 不能默认认为全局状态覆盖它 |
| 数据读取位置 | 按DataLoader与采样策略设计 | RNG状态不等于批次游标 |
Accelerate当前官方checkpoint实现保存Python random、NumPy全局随机状态和PyTorch CPU随机状态,并按可用设备保存相应状态,例如CUDA。这里的“NumPy全局状态”不意味着每一个default_rng实例都被自动识别。

把继续训练做成明确的入口选择
下面脚本使用可选的--resume参数表示操作者选择的断点目录。Progress保存下一次应开始的epoch。数据由arange生成,避免重新构造数据时抽取随机样本;网络保留Dropout,以体现训练期间存在随机操作。
import argparse
from pathlib import Path
import torch
from torch import nn
from torch.utils.data import DataLoader, TensorDataset
from accelerate import Accelerator
from accelerate.utils import set_seed
class Progress:
def __init__(self):
self.next_epoch = 0
def state_dict(self):
# 保存业务进度,而不是把epoch当成随机状态。
return {"next_epoch": self.next_epoch}
def load_state_dict(self, state):
self.next_epoch = int(state["next_epoch"])
parser = argparse.ArgumentParser()
parser.add_argument("--resume", default=None)
parser.add_argument("--epochs", type=int, default=4)
parser.add_argument("--output", default="./training-states")
args = parser.parse_args()
# 示例只针对单进程CPU;继续模式稍后会覆盖初始化期间的随机状态。
accelerator = Accelerator(cpu=True, mixed_precision="no")
set_seed(31415)
x = torch.arange(256, dtype=torch.float32).reshape(64, 4) / 256
y = x.sum(dim=1, keepdim=True)
loader = DataLoader(TensorDataset(x, y), batch_size=8, shuffle=False, num_workers=0)
model = nn.Sequential(nn.Linear(4, 12), nn.ReLU(), nn.Dropout(0.2), nn.Linear(12, 1))
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
model, optimizer, loader = accelerator.prepare(model, optimizer, loader)
progress = Progress()
accelerator.register_for_checkpointing(progress)
if args.resume:
# 初始化和prepare必须在恢复前完成;只加载自己生成的可信断点。
accelerator.load_state(args.resume)
accelerator.print(f"继续训练,起始epoch={progress.next_epoch}")
else:
accelerator.print("从头开始训练")
# 加载后不重新设置seed,不插入随机抽样日志。
for epoch in range(progress.next_epoch, args.epochs):
model.train()
for inputs, targets in loader:
optimizer.zero_grad()
loss = nn.functional.mse_loss(model(inputs), targets)
accelerator.backward(loss)
optimizer.step()
progress.next_epoch = epoch + 1
checkpoint = Path(args.output) / f"epoch-{progress.next_epoch:03d}"
if checkpoint.exists():
# 不覆盖已有断点;改用新的输出根目录继续训练。
raise FileExistsError(f"断点目录已存在:{checkpoint}")
accelerator.save_state(str(checkpoint))
accelerator.print(f"断点保存完成:{checkpoint}")
这是一个独立的最小训练例子,不包含学习率调度器。已有项目若使用调度器,应按项目的prepare或登记方式一起恢复,不能只借用其中的RNG部分。恢复目录不存在、对象不匹配或加载报错时,应让继续操作失败并给出错误,而不是悄悄退回从头训练。
# 先训练到第二个完整epoch,生成独立断点目录。 python train.py --epochs 2 --output ./training-states # 继续到第四个epoch;总目标epochs不是“再训练四轮”。 python train.py --resume ./training-states/epoch-002 --epochs 4 --output ./continued-states
代码打印的是状态提示,不是精确复现证明。本文没有展示损失曲线、随机输出或性能测量结果。接口以当前官方文档为依据;项目应记录实际安装的Accelerate、PyTorch与NumPy版本,保存和恢复使用相同依赖环境,不把跨版本兼容当成承诺。
自建NumPy生成器要保存自己的状态
如果训练逻辑使用np.random.default_rng,生成器对象维护独立状态。以下封装可加入前面的单进程脚本,在load_state之前创建并登记,随后业务代码通过noise.rng取随机数。保存和恢复时必须使用相同登记集合与顺序。
import copy
import numpy as np
class LocalNoise:
def __init__(self, seed):
self.rng = np.random.default_rng(seed)
def state_dict(self):
# 显式保存该实例的位生成器状态,避免误用全局随机状态。
return {"bit_generator": copy.deepcopy(self.rng.bit_generator.state)}
def load_state_dict(self, state):
self.rng.bit_generator.state = state["bit_generator"]
# 插在accelerator.load_state之前,保存与恢复两种入口都要登记。
noise = LocalNoise(2718)
accelerator.register_for_checkpointing(noise)
NumPy的Generator文档区分了独立生成器与全局实例,BitGenerator.state提供状态读写入口。此封装示例不是对任意生成器类型的兼容转换。多进程训练中,如果每个rank的自建生成器状态不同,还需要明确逐rank保存设计,不能将这段单进程封装直接视作所有进程状态的完整备份。多进程save_state/load_state也不应仅放入主进程条件分支;各训练进程应按相同控制逻辑参与,保留对应状态。

数据位置和额外开销不能藏在继续按钮后面
完整epoch边界保存省去了中途批次定位,这也是本文示例选它的原因。如果需要epoch中途暂停,还要登记已完成批次数,并依据数据加载器策略恢复读取位置。官方提供skip_first_batches跳过前面批次,但跳过批次不是通用的采样器、worker随机增强和预取队列状态恢复方案。
界面或命令提示中应区分“指定了断点”“完成加载”和“已经开始继续训练”。错误目录、损坏状态或依赖不匹配不能显示成恢复成功。可读状态文字应包含断点标识与业务进度,不只用颜色表达状态,也不要把未知剩余时长显示为准确倒计时。
保存完整状态需要磁盘空间和写入时间。checkpoint频率应根据可接受的重算量与写入成本选择,不能宣称频繁保存没有开销。真正要求连续训练与恢复训练一致时,还要控制硬件、精度、算子确定性、数据顺序和训练拓扑;保存RNG只是必要组成之一,不构成逐位一致保证。
常见问题
rng_types是不是随机状态保存开关?
不是。Accelerator API将它定义为prepared DataLoader迭代时的随机数同步配置;训练断点保存和加载仍使用save_state/load_state。
只调用save_model,恢复Dropout序列就够了吗?
不够。模型导出与训练状态保存目的不同,继续训练还需要优化器、RNG以及业务进度等材料。
恢复后能先运行随机增强预览吗?
如果预览使用训练同一发生器,会消耗随机状态。应与训练发生器分离,或在预览结束后明确恢复原状态,不能忽略这次消耗。
换GPU数量后还算精确恢复吗?
不能直接承诺。进程对应关系、采样分片和计算行为都可能变化,应作为新配置处理,而不是凭断点存在宣称完全一致。
继续训练的核心不是记住最初seed,而是把训练对象、随机发生器状态和业务进度一起放回暂停时的位置。先用完整epoch边界建立可靠的保存入口,再为独立生成器和中途数据位置补充各自的状态设计。
Diffusers怎样使用Generator复现同一张生成图
- 上一篇
- Diffusers怎样使用Generator复现同一张生成图
- 下一篇
- Diffusers CPU卸载与直接放入GPU有什么区别
-
- 科技周边 · 人工智能 | 1小时前 | python · 人工智能 · Transformers apply_chat_template 聊天模板 chat_template 角色标签
- Transformers聊天模板与手写角色标签有什么兼容性差异
- 492浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- Diffusers怎样使用Generator复现同一张生成图
- 118浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 | 模型 混合精度 优化器 分布式训练 Accelerate Accelerator.prepare
- Accelerate prepare为什么要同时接收模型与优化器
- 386浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 | 人工智能 · Hugging Face Datasets streaming IterableDataset Dataset.shuffle shuffle buffer
- Datasets流式读取与内存数据集的shuffle有什么区别
- 130浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- Hugging Face Datasets map怎样同时删除旧字段
- 421浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- PEFT适配器检查点为什么不包含完整基础模型
- 301浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 | python · Hugging Face 提示词 Transformers generate input_ids
- Transformers生成结果为什么包含输入提示词
- 111浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 | 解码 token Transformers generate 新生成内容
- Transformers怎样只解码新生成的token
- 461浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 | python · 人工智能 · Transformers offset_mapping 原始文本 Fast tokenizer 文本偏移
- Transformers分词偏移怎样映射回原始文本片段
- 330浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 | Transformers 固定长度 tokenizer 动态补齐 DataCollatorWithPadding
- Transformers批次分词时动态补齐与固定长度补齐怎么选
- 153浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 463次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 526次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 543次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 492次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 311次使用
-
- 本地大模型反复输出同一句话怎么调整生成参数
- 2026-09-06 501浏览
-
- Python 调用大模型时如何用结构化输出校验 JSON:从解析失败到可重试
- 2026-08-29 501浏览
-
- AI写作工具免费版安装教程(含豆包Clawdbot)
- 2026-05-30 501浏览
-
- WPS AI能自动生成PPT吗?输入主题一键制作演示文稿
- 2026-05-27 501浏览
-
- Canva手机闪退解决方法及适配指南
- 2026-05-25 501浏览

