class_docstr: 通过该 callback 来测试 Trainer 的 accumulation_steps 是否实现正确；
  
  1. 在每一个 batch 检验模型是否正确地得到了更新（只有每隔 accumulation_steps 模型的参数才应该改变）；
  2. 检验 optimizer 的参数是否只在正确的时刻进行了清零；
code: def on_train_batch_end(self, trainer):
      # 注意这里的 trainer.global_forward_steps 的值比 trainer 上一次调用 batch_step_fn 的值大一；
      if (
          trainer.global_forward_batches % trainer.accumulation_steps
          == 0
      ):
          # 模型的参数应该与上一个 batch 不同；
          cur_batch_params = deepcopy(
              next(trainer.driver.unwrap_model().parameters())
              .cpu()
              .detach()
          )
          if self.last_batch_params is not None:
              assert not cur_batch_params.equal(self.last_batch_params)
              if cur_batch_params.equal(self.last_batch_params):
                  self.equal += 1
  
          # optimizer 的梯度应该得到了清零；
          optimizers = trainer.driver.optimizers
          for optimizer in optimizers:
              param_groups = optimizer.param_groups
              for group in param_groups:
                  for p in group["params"]:
                      assert p.grad is None or p.grad.equal(
                          torch.zeros_like(p.grad)
                      )
      else:
          # 模型的参数应该与上一个 batch 相同；
          cur_batch_params = deepcopy(
              next(trainer.driver.unwrap_model().parameters())
              .cpu()
              .detach()
          )
          if self.last_batch_params is not None:
              assert cur_batch_params.equal(self.last_batch_params)
  
          # optimizer 的梯度不应该得到了清零；
          optimizers = trainer.driver.optimizers
          for optimizer in optimizers:
              param_groups = optimizer.param_groups
              for group in param_groups:
                  for p in group["params"]:
                      assert p.grad is not None and not p.grad.equal(
                          torch.zeros_like(p.grad)
                      )
  
      self.last_batch_params = cur_batch_params
  
imports: from copy import deepcopy
  from fastNLP.core.callbacks.callback import Callback
  from fastNLP.envs.imports import _NEED_IMPORT_TORCH
label_desc: Use image node_id 2 for calling the RecordAccumulationStepsCallback_Torch obj's underlying member method code with example usage: obj.on_train_batch_end(trainer) without return types