15 KiB
训练器(Solvers)
总览
Solver是对模型训练、验证和测试过程的一个流程定义。 在Solver中,会根据配置yaml文件的设置,对数据(data),模型(model),优化器(optimizer)和调度(scheduler)等需要的模块进行逐一初始化。 每一个具体的任务的自定义Solver都要继承自BaseSolver。
在某些特殊场景下,还需要初始化一些自定义的模块。例如,在训练过程中记录保存中间结果需要用到Hooks;在训练过程中验证需要定义Metrics等等。
基础用法
子Solver继承时的用法:
from scepter.modules.solver.registry import SOLVERS
from scepter.modules.solver import BaseSolver
@SOLVERS.register_class()
class XxxSolver(BaseSolver):
def __init__(self, cfg, logger=None):
super().__init__(cfg, logger=logger)
实际启动Solver的使用方式见scepter.modules/task/cate_recognition中run_task.py和run_inference.py:
solver = SOLVERS.build(cfg.SOLVER, logger=std_logger)
scepter.modules.solver.BaseSolver
Solver的基类,是通过元类ABCMeta定义的抽象基类,支持注册操作。自定义的solver均应该是该类的子类,并且进行注册。
BaseSolver是一个具体实现Solver的案例,展示了使用pytorch_lightning和不使用时两种Solver的写法。 在实际使用中情况各异,因此Solver的使用也比较灵活,其中大部分的成员函数均可以按照需求在子类中,被复写或者新加好用的功能,甚至直接写新的函数代替。
function __init__
(cfg: scepter.modules.utils.config.Config, logger = None) -> None
初始化Solver类,从cfg中获取并定义一些必要的参数。
部分在__init__中初始化的参数,详情见代码:
Configs
- FILE_SYSTEM —— (cfg) 文件系统配置,默认None.
- WORK_DIR —— (str) 工作路径定义.
- LOG_FILE —— (str) Log文件的位置.
- RESUME_FROM —— (str) 恢复训练模型保存的中间结果.
- MAX_EPOCHS —— (int) 训练最大epochs数.
- ACCU_STEP —— (int) When use ddp, the grad accumulate steps for each process,默认1.
- NUM_FOLDS —— (int) Num folds for training,默认1.
- EVAL_INTERVAL —— (int) Eval the model interval,默认1.
- EXTRA_KEYS —— (List) The extra keys for metrics,默认[].
- TRAIN_DATA —— (cfg) 训练数据配置.
- EVAL_DATA —— (cfg) 验证数据配置.
- TEST_DATA —— (cfg) 测试数据配置.
- TRAIN_HOOKS —— (List) 训练HOOKS.
- EVAL_HOOKS —— (List) 验证HOOKS.
- TEST_HOOKS —— (List) 测试HOOKS.
- MODEL —— (cfg) 模型配置.
- OPTIMIZER —— (cfg) 优化器配置.
- LR_SCHEDULER —— (cfg) 学习率Scheduler配置.
- METRICS —— (List) Metrics.
Parameters
- cfg —— The Config used to build solver.
- logger —— Instantiated Logger to print or save log.
function set_up_pre
() -> None
配置环境、日志路径,调用construct_hook来初始化hook等等。
与pytorch_lightning二选一,在不使用pytorch_lightning(use_pl=Flase)时调用。需要在启动其他所有操作之前调用。
function set_up
() -> None
配置数据、模型、metrics、优化器及pytorch_lightning环境(如果使用的话)。
function construct_data
() -> None
实际数据的构建方法,默认会在self.set_up中被调用,包括TRAIN_DATA、EVAL_DATA、TEST_DATA。将实例化的结果写入self.datas中。
function construct_hook
() -> None
实际Hook的构建方法,默认会在self.set_up_pre中被调用,包括TRAIN_HOOKS、EVAL_HOOKS、TEST_HOOKS。将实例化的结果写入self.hooks_dict中。
function construct_model
() -> None
实际Hook的构建方法,默认会在self.set_up中被调用,将实例化的结果作为self.model。
function model_to_device
() -> None
实际Metrics的构建方法,默认会在self.set_up中被调用,将实例化的结果写入self.metrics。
function model_to_device
(tg_model_ins=None) -> None or MODELS
模型的配置方法,包括模型分片等分布式配置,默认会在self.set_up中被调用。
Parameters
- tg_model_ins —— 待配置的model,如果为None,默认使用self.model。
Returns
- tg_model_ins —— 配置好的model。如果tg_model_ins为None,则无返回值。
function init_opti
() -> None
优化器的配置方法,默认会在self.set_up中被调用。将实例化的optimizer和lr_scheduler分别作为self.optimizer和self.lr_scheduler。
function solve
(epoch = None, every_epoch = False) -> None
执行实际的训练、验证或者测试操作,执行self.solve_train、self.solve_eval、self.solve_test等。 并且在执行前后分别调用self.before_solve、self.after_solve来进行Hook的记录。
Parameters
- epoch —— 设定epoch数量。
- every_epoch —— 与self.solve_train、self.solve_eval、self.solve_test的实现方式及Data的配置有关,标记是否每个epoch都需要重新调用一遍。 以self.solve_train为例,如果实现方式是调用一次执行一个epoch,则every_epoch应为True;如果调用一次调用会执行到所有epoch都结束,则应为False。
function solve_train
() -> None
调用self.run_train,执行train。 并且在执行前后分别调用self.before_epoch、self.after_epoch来进行Hook的记录。
function solve_eval
() -> None
调用self.run_eval,执行eval。 并且在执行前后分别调用self.before_epoch、self.after_epoch来进行Hook的记录。
function solve_test
() -> None
调用self.run_test,执行test。 并且在执行前后分别调用self.before_epoch、self.after_epoch来进行Hook的记录。
function before_solve
() -> None
在实际执行run_xxx之前,进行Hook的记录。
function after_solve
() -> None
在执行run_xxx之后,再次进行Hook的记录。
function run_train
() -> None
循环调用self.run_step_train,执行一个epoch或者所有epoch的训练过程。 并且在循环开始及结束后分别调用self.before_all_iter、self.after_all_iter来进行Hook的记录。 并且在每次循环调用self.run_step_train前后,分别调用self.before_iter、self.after_iter来进行Hook的记录。
function run_eval
() -> None
循环调用self.run_step_eval,执行一个epoch或者所有epoch的验证过程。 并且在循环开始及结束后分别调用self.before_all_iter、self.after_all_iter来进行Hook的记录。 并且在每次循环调用self.run_step_eval前后,分别调用self.before_iter、self.after_iter来进行Hook的记录。
function run_test
() -> None
循环调用self.run_step_test,执行一个epoch或者所有epoch的验证过程。 并且在循环开始及结束后分别调用self.before_all_iter、self.after_all_iter来进行Hook的记录。 并且在每次循环调用self.run_step_test前后,分别调用self.before_iter、self.after_iter来进行Hook的记录。
function run_step_train
(batch_data, batch_idx = 0, step = None, rank = None) -> None
执行一个batch的模型推理。
function run_step_eval
(batch_data, batch_idx = 0, step = None, rank = None) -> None
执行一个batch的模型推理。
function run_step_test
(batch_data, batch_idx = 0, step = None, rank = None) -> None
执行一个batch的模型推理。
function register_flops
(Dict data, keys = []) -> None
使用fvcore进行flops计算,结果保存在self._model_flops中。
Parameters
- data —— 输入模型的data,格式为key-value结构,value为Tensor或者List,默认只取batch维度的第一个元素来保证batchsize=1。
- keys —— 指定使用keys中的元素所对应的value作为模型输入。如果keys为空,则去data中所有的value。
function before_epoch
() -> None
在每个epoch开始前执行。run_xxx前执行。
function before_all_iter
() -> None
在每个epoch开始前执行。循环调用run_step_xxx的循环前执行。
function before_iter
() -> None
在每个step开始前执行。run_step_xxx前执行。
function after_epoch
() -> None
在每个epoch开始后执行。run_xxx后执行。
function after_all_iter
() -> None
在每个epoch开始后执行。循环调用run_step_xxx的循环后执行。
function after_iter
() -> None
在每个step开始后执行。run_step_xxx后执行。
function collect_log_vars
() -> OrderedDict
获取需要在log中保存的变量。
Returns
- ret —— 返回需要的变量。
Hooks
总览
在Solver执行过程中,需要打印日志、记录Tensorboard、梯度计算和更新、保存中间模型参数、保存测试结果等,这些都需要Hook去执行。
基础用法
新建Hook的方法:
from scepter.modules.solver.hooks.hook import Hook
from scepter.modules.solver.hooks.registry import HOOKS
@HOOKS.register_class()
class XxxHook(Hook):
def __init__(self, cfg, logger=None):
super(XxxHook, self).__init__(cfg, logger=logger)
scepter.modules.solvers.hooks.Hook
定义了一个标准的Hook类的基类,定义了详细的成员函数列表。继承自该类的子类均需要在这些成员函数中挑选部分进行实现。 成员函数包括:
function init
(cfg: scepter.modules.utils.config.Config, logger = None) -> None 初始化logger。
function before_solve
(solver) -> None
开始solve之前执行。
function after_solve
(solver) -> None
结束solve之后执行。
function before_epoch
(solver) -> None
每个epoch之前执行。
function after_epoch
(solver) -> None
每个epoch之后执行。
function before_all_iter
(solver) -> None
迭代开始之前执行。
function after_all_iter
(solver) -> None
迭代结束之后执行。
function before_iter
(solver) -> None
每个step之前执行。
function after_iter
(solver) -> None
每个step之后执行。
scepter.modules.solver.hooks.CheckpointHook
在solve开始之前,加载checkpoint。加载模型的路径来自Solver的RESUME_FROM参数。依赖于Solver中实现的load_checkpoint成员函数。
每个epoch结束之后,保存checkpoint。
Configs
- PRIORITY —— (int)默认为_DEFAULT_CHECKPOINT_PRIORITY=300
- INTERVAL —— (int)保存checkpoint的epoch间隔,默认为1
- SAVE_NAME_PREFIX —— (str)保存checkpoint的前缀名,默认为'ldm_step'
- SAVE_LAST —— (bool)是否保存最后iter的checkpoint,默认为False,作用于after_iter中。
- SAVE_BEST —— (bool)是否保存最好的checkpoint,默认为True,作用于after_epoch中。需要同时设置SAVE_BEST_BY,否则退回默认False。
- SAVE_BEST_BY —— (str)判断最好的指标,默认越大越好
scepter.modules.solver.hooks.BackwardHook
在每步迭代之后执行的内容。包括loss的反传,optimizer的步数配置等等。
Configs
- PRIORITY —— (int)_DEFAULT_BACKWARD_PRIORITY=0
- GRADIENT_CLIP —— (int)torch.nn.utils.clip_grad_norm_中max_norm参数,默认为-1。小于等于0时不生效。
- ACCUMULATE_STEP —— (int)用于设置梯度累计的步数
- EMPTY_CACHE_STEP —— (int)torch.cuda.empty_cache每多少步清除一下memory,默认为-1。小于等于0时不生效。
scepter.modules.solver.hooks.LogHook
日志Hook。
Configs
- PRIORITY —— (int)__DEFAULT_LOG_PRIORITY=100
- SHOW_GPU_MEM —— (bool)判断是否打印内存使用情况
- LOG_INTERVAL —— (int)打印log的步数间隔,默认为10。小于等于0时不生效。
scepter.modules.solver.hooks.TensorboardLogHook
Tensorboard日志Hook。
Configs
- PRIORITY —— (int)__DEFAULT_LOG_PRIORITY=100
- LOG_DIR —— (str)存储Tensorboard log的路径。
- LOG_INTERVAL —— (int)打印log的步数间隔,默认为1000。
scepter.modules.solver.hooks.LrHook
学习率变化Hook。
Configs
- PRIORITY —— (int)_DEFAULT_LR_PRIORITY=200
- WARMUP_FUNC —— (str)warmup的方式:仅支持"linear",默认为"linear"。
- WARMUP_EPOCHS —— (int)warmup epoch数,默认为1。
- WARMUP_START_LR —— (float)warmup初始学习率,默认为0.0001。
- SET_BY_EPOCH —— (bool)是否每个epoch设置一次学习率,默认为True。False则每个step设置一次。
scepter.modules.solver.hooks.DistSamplerHook
每个epoch开始之前,采样一个epoch的数据。
Configs
- PRIORITY —— (int)__DEFAULT_SAMPLER_PRIORITY=400
scepter.modules.solver.hooks.ProbeDataHook
用于打印probe存储的train/eval中间(可视化)结果。
Configs
- PRIORITY —— (int)_DEFAULT_LR_PRIORITY=200
- PROB_INTERVAL —— (int)打印probe的步数间隔,默认为1000。
scepter.modules.solver.hooks.SafetensorsHook
用于存储.safetensors格式的模型文件。
Configs
- PRIORITY —— (int)_DEFAULT_LR_PRIORITY=200
- INTERVAL —— (int)存储的步数间隔,默认为1000。
- SAVE_NAME_PREFIX —— (str)保存文件的前缀名。