Page 36 · SimLabs LLM Visual

保存、加载、继续训练:把训练成果留下来

上一页我们训练了一个能生成文字的 Mini-GPT。但有个问题:一旦关掉浏览器,一切归零。真实的大模型训练要跑几周,中途断电、重启、调参都是家常便饭。所以必须有一套机制,把训练到一半的模型“拍个快照”存下来,下次能原样恢复、继续训练。这一页会把保存、加载、继续训练这条流水线彻底讲透。

看懂检查点 理解序列化 掌握优化器状态恢复 亲手保存和加载

为什么训练好的模型必须能保存

训练一个模型可能花费数小时、数天甚至数周。如果训练完不能保存,那所有计算都白费了。保存和加载是训练系统里最基础、也最容易被忽视的一环。

① 训练可能中断

断电、机器故障、抢占式实例被回收、代码 bug 崩溃……真实训练环境充满不确定性。定期保存检查点,可以让训练从中断点恢复,而不是从头再来。

② 需要多阶段训练

先预训练,再微调,再对齐,再蒸馏。每个阶段都从上一阶段的权重出发。没有保存加载机制,这些流程根本无法串联。

③ 模型需要部署

训练好的模型要部署到服务器、边缘设备、浏览器。训练和推理是分开的,必须有一个标准格式把权重从训练环境传到推理环境。

先抓住一句话: 保存不只是“存权重”,而是把训练现场的完整状态拍成快照——模型参数、优化器状态、训练步数、配置、词表。加载时原样恢复,才能真正无缝继续训练。

实验台:亲手保存一个检查点,再加载回来

下面是一个真实可训练的小模型(约 900 个参数)。你可以先训练几步,然后保存一个检查点,再重置模型,最后加载检查点继续训练。全程观察 loss 的变化,理解“继续训练”和“从头训练”的区别。

① 训练 → ② 序列化 → ③ 存入存储 → ④ 反序列化 → ⑤ 继续训练

1训练模型

每次点击“训练”会执行 50 步梯度下降。观察 loss 下降、参数更新的过程。

0.010
// 模型已初始化,等待训练...

2保存检查点

给当前模型状态起个名字,然后保存到浏览器存储。检查点会包含:模型参数、优化器状态、训练步数、loss 历史。

3检查点仓库

所有已保存的检查点都在这里。点击“加载”可以把模型恢复到那个时刻,点击“删除”可以移除。

// 还没有保存任何检查点

📊当前模型状态

训练步数
0
当前 Loss
—
参数量
—
Adam 步数 t
0
Loss 历史(最近 50 次记录):

🔍检查点序列化预览

保存时,模型会被转换成 JSON 字符串。这是它长什么样子的预览:

// 保存一个检查点后,这里会显示序列化内容

一个检查点里到底存了什么

很多人以为保存模型就是保存权重。其实,要完整恢复训练现场,检查点至少要包含四类信息。

① 模型参数(Model State)

这是最核心的部分:每一层权重矩阵、偏置、LayerNorm 的 γ 和 β。对于 LLM,这是几十亿到几千亿个浮点数。保存时必须保证精度一致(FP32 / FP16 / BF16)。

// 模型参数示例(本页面的小模型)
W1: [V, H] = [26, 16]
b1: [H] = [16]
W2: [H, V] = [16, 26]
b2: [V] = [26]

② 优化器状态(Optimizer State)

AdamW 的每个参数都有一阶矩 m 和二阶矩 v。如果不保存这些,加载后 Adam 会从零开始累积,导致前几百步更新方向错误,loss 出现 spike。这是“继续训练”和“从头训练”的关键区别。

// AdamW 状态
mW1, vW1: [V, H] = [26, 16]
mW2, vW2: [H, V] = [16, 26]
mb1, vb1: [H] = [16]
mb2, vb2: [V] = [26]
t: 全局步数

③ 训练元数据(Training Metadata)

当前是第几步、学习率是多少、loss 曲线、验证集指标。这些信息决定了加载后从哪个学习率继续、是否需要调整调度器。没有它,你只能盲猜。

// 训练元数据
step: 1500
lr: 0.003
loss: 1.24
best_val_loss: 1.18

④ 配置与词表(Config & Vocab)

模型结构(多少层、多少头、维度多少)、词表映射(字符 → id)、特殊 token 定义。没有这些,加载后的权重就是一堆无意义的数字。

// 配置与词表
V: 26, H: 16, CTX: 32
vocab: ['<unk>', '今', '天', ...]
stoi: {'今': 1, '天': 2, ...}
真实 LLM 的检查点: GPT-3 175B 参数,FP16 存储约 350GB,加上 Adam 状态(m 和 v)总共约 1.05TB。所以大模型训练必须用分布式存储、分片保存(ZeRO)、异步上传等技术,不能简单写一个文件。

检查点存到哪里:四种方案对比

本页面用 localStorage 演示,因为它最简单、同步、浏览器原生支持。真实训练中会根据规模选择不同的存储方案。

方案 容量 速度 持久性 典型场景
localStorage 5~10 MB 快 浏览器内持久 教学演示、小模型
IndexedDB 几百 MB ~ GB 中 浏览器内持久 浏览器端训练、PWA
文件系统 / 对象存储 无限 取决于网络 持久、可备份 真实训练(S3、HDFS)
分布式存储(分片) TB ~ PB 高吞吐 持久、容错 大模型训练(ZeRO)
大模型为什么需要分片保存: 一个 175B 模型加优化器状态约 1TB,单机内存和磁盘都放不下。ZeRO 技术把参数、梯度、优化器状态切分到多张 GPU 上,保存时每个 GPU 各写自己负责的片段,加载时再合并。这样既节省内存,又能并行加速 I/O。

知识点完整总结

下面用六张卡片,把保存、加载、继续训练相关的每一个概念完整讲清楚。

📖 标准介绍

检查点(Checkpoint)是训练过程中保存的模型状态快照,包含模型参数、优化器状态、训练元数据和配置信息。保存检查点称为 checkpointing,加载检查点恢复训练称为 resume from checkpoint。

序列化(Serialization)是把内存中的模型对象转换为可存储/传输的格式(JSON、二进制、Protobuf 等)的过程。反序列化则相反。PyTorch 常用 state_dict() 和 torch.save(),TensorFlow 用 tf.train.Checkpoint,HuggingFace 用 save_pretrained()。

检查点分为全量检查点(包含所有状态)和推理检查点(只含模型参数,不含优化器状态)。

💡 通俗介绍

想象你在玩一个很长的 RPG 游戏。你不能一口气通关,所以每次打到某个进度,就存一个档。下次打开游戏,从存档点继续,而不是重新开始。

训练模型也是一样。模型从随机参数出发,每走一步就更新一次参数。如果中途关掉,所有进度都会丢失。检查点就是这个“游戏存档”——它记录了模型当前学到哪儿了、优化器当前的“惯性”是多少、已经走了多少步。

为什么优化器状态也要存? 因为 Adam 不是无记忆的。它记住了每个参数过去梯度的均值和方差。如果只存模型参数,加载后 Adam 相当于失忆了,前几百步会“瞎走”。所以真正的检查点必须包含优化器状态。

🔧 解决了什么问题

它解决了“如何让长时间训练可中断、可恢复、可复用”这个问题。

  • 容错:机器故障、断电、抢占式实例回收时,从最近检查点恢复,不浪费已训练的时间。
  • 多阶段训练:预训练 → 微调 → 对齐 → 蒸馏,每个阶段从上一阶段的权重出发。
  • 实验复现:保存每个实验的检查点,可以对比、回滚、复现。
  • 模型分发:训练好的模型打包成标准格式,部署到不同推理环境。
  • 继续训练:从检查点恢复训练时,优化器状态一起恢复,保证 loss 曲线连续。
  • 增量训练:在新数据上继续训练已有模型,不用从头开始。

⭐ 为什么重要

保存和加载是训练系统的基础设施。没有它,大规模训练根本不可能进行。

它影响:

  • 训练能否从中断中恢复;
  • 多阶段流水线能否串联;
  • 模型能否被部署和复用;
  • 实验结果能否被复现;
  • 训练成本能否被控制(避免重跑)。

在 LLM 训练中,检查点保存是 I/O 密集型的核心环节。保存策略(频率、分片、异步)直接影响训练吞吐。好的检查点系统能让训练在故障时只损失几分钟,而不是几天。

🚀 应用场景

  • LLM 预训练:每几千步保存一次,支持断点续训。
  • 微调:从预训练检查点出发,训练后保存微调检查点。
  • RLHF / DPO:多个训练阶段之间传递检查点。
  • 模型蒸馏:教师模型检查点用于指导学生模型。
  • 持续学习:在新数据上增量更新已有模型。
  • 联邦学习:客户端本地训练后,上传检查点或梯度。
  • 浏览器端训练:用 IndexedDB 保存小型模型。
  • 边缘部署:把检查点转成 ONNX / TFLite / GGUF 等推理格式。
  • 实验管理:MLflow、Weights & Biases 等平台管理检查点版本。

⚠️ 缺陷与局限

  • 存储开销巨大:LLM 检查点动辄数百 GB 到 TB 级。需要高速存储和高带宽网络。
  • 保存时阻塞训练:同步保存会让训练暂停数秒到数分钟。需要异步保存、分片并行写入。
  • 格式兼容性:不同框架、不同版本的检查点格式可能不兼容,迁移困难。
  • 精度问题:FP16 保存可能导致精度损失,影响继续训练。关键模型需要 FP32 master weights。
  • 优化器状态遗漏:只保存模型参数而不保存优化器状态,会导致继续训练时 loss spike。这是新手常犯的错误。
  • 版本管理复杂:检查点太多难以管理,需要保留策略(只留最近 N 个 + 最佳 N 个)。
  • 安全性:检查点可能包含敏感训练数据的信息,需要加密和访问控制。
  • 分布式一致性:多 GPU 训练时,各设备状态必须一致地保存和恢复,否则会出错。
一句话理解保存与加载: 检查点是训练现场的完整快照,包含模型参数、优化器状态、训练元数据和配置。保存让训练可中断、可恢复、可复用;加载让模型可以从任意时刻继续。它是连接训练、微调、部署的桥梁——没有它,所有训练成果都是一次性的。

学完这一页,最好记住三件事

检查点不只是权重

优化器状态(Adam 的 m 和 v)、训练步数、学习率调度器状态都必须一起保存,否则继续训练时 loss 会跳。

序列化格式决定兼容性

JSON 通用但臃肿,二进制紧凑但需要框架支持。PyTorch 的 .pt、HuggingFace 的 safetensors、GGUF 各有适用场景。

保存策略影响训练效率

保存太频繁拖慢训练,太少又容易丢进度。大模型训练通常用异步保存 + 分片并行,平衡安全与速度。