Files

15 KiB
Raw Permalink Blame History

训练器(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)保存文件的前缀名。