实现本地训练保存CheckPoint的机制
Created by: reyoung
如果我们要实现可伸缩的Paddle调度,实现训练保存CheckPoint的机制是一个非常紧急的需求。如果要实现伸缩训练,那我们首先要实现如何保存本地训练的CheckPoint,进而使用CheckPoint可以精度无损的恢复训练过程。
现状
Paddle只有保存/载入模型参数的功能,我们在训练模型时不能精度无损的恢复训练。Paddle中实现了很多动态学习率优化算法,例如AdaGrad,Adam等。这些优化算法通过记录和处理梯度的历史信息来动态的调整学习率。这些『参数历史信息』、每个参数的『当前学习率』、必要的『中间变量』都需要保存下来才能精度无损的恢复训练。
同时,Paddle的一些Layer本身也需要保存一些模型之外的信息,用于恢复训练或模型预测。例如,BatchNormalization Layer 需要保存当前的滑动平均值和方差来恢复训练。目前,我们使用了构造一个特殊的参数来完成这一功能,但滑动平均值和方差不应该是模型参数的一部分。
目前的参数保存也只支持序列化到文件,这和我们使用Kubernetes开发Paddle Cloud的要求不符。
要求
基于以上现状,对Paddle保存CheckPoint的机制有如下要求:
- 保存CheckPoint的方法不能将CheckPoint直接序列化到文件,而是应该将其序列化到文件流。这样做我们既能简单的完成保存本地文件,也能将CheckPoint通过网络或者其他手段发送出去。
*这个机制 可以序列化不同数据类型。仅仅Optimizer需要保存的类型就有
real
,std::vector<int64_t>
,paddle::Vector
等类型。 - 这个机制需要在运行时注册需要被序列化变量。因为同一个神经网络使用不同的优化算法需要序列化的变量是不同的。而使用何种优化算法是运行时才能决定的。
- 这个机制不只要支持序列化Optimizer中的变量,还要支持更多通用的序列化方式。为了无损的恢复训练,Paddle需要在很多地方都有这种保存机制。
何时调用保存CheckPoints
训练过程保存CheckPoint会以C-API形式对外提供,它可以在任何时候被调用。何时被调用交由更高层的程序或者用户决定。
例如在event_handler
中使用trainer.serialize_checkpoint()
即可保存在trainer中当前的CheckPoint。
哪个进程会保存CheckPoints
本Issue中保存CheckPoint的问题讨论只局限在『单机恢复训练』这一场景中。
但进一步来讲,只有在多机训练中便有哪个进程保存CheckPoints的问题。当前ParameterServer中包含了Optimizer,而在Trainer端包含了Layer的信息。两者都需要保存部分的CheckPoints。因此两个进程需要同时保存CheckPoints。
但如何同时保存CheckPoints和多机环境下需要保存哪些信息不在本issue讨论范围内。
如何实现该CheckPoint机制
本issue意在说明我们需要保存CheckPoint的机制和该机制需要完成哪些工作。如何实现该机制由后续设计文档说明。
Related issue #1960 (closed)