class_docstr: A base runner for training without training tricks.
  Applying training tricks such as ensemble of template or verbalizer,
  or self-training can use other runner class.
  This class is specially implemented for classification.
  For generation task, though it can be integrated in this class
  via `task` option, we keep it as another class for simplicity.
  
  Args:
      model (:obj:`nn.Module`): One ``nn.Module`` object.
      train_dataloader (:obj:`PromptDataloader`, optional): The dataloader to bachify and process the training data.
      valid_dataloader (:obj:`PromptDataloader`, optionla): The dataloader to bachify and process the val data.
      test_dataloader (:obj:`PromptDataloader`, optional): The dataloader to bachify and process the test data.
      config (:obj:`CfgNode`): A configuration object.
      loss_function (:obj:`Callable`, optional): The loss function in the training process.
code: def save_checkpoint(
      self,
      ckpt: str,
      save_state=True,
      extra: dict = {},
      copy: str = None,
  ):
      if self.clean:
          return
      logger.info(f"Saving checkpoint {self.checkpoint_path(ckpt)}...")
      state_dict = {
          "state_dict": self.inner_model.state_dict(),
      }
      state_dict.update(extra)
  
      if save_state:
          state_dict["optimizer"] = [
              opt.state_dict()
              if isinstance(opt, torch.optim.Optimizer)
              else None
              for opt in self.optimizers
          ]
          with warnings.catch_warnings(record=True):
              state_dict["scheduler"] = [
                  sch.state_dict()
                  if isinstance(
                      sch, torch.optim.lr_scheduler._LRScheduler
                  )
                  else None
                  for sch in self.schedulers
              ]
  
          state_dict.update(
              {
                  "cur_epoch": self.cur_epoch,
                  "best_score": self.best_score,
                  "global_step": self.global_step,
              }
          )
      torch.save(
          state_dict, self.checkpoint_path(ckpt), pickle_module=dill
      )
      if copy:
          logger.info(
              f"Copying checkpoint {self.checkpoint_path(ckpt)} to {self.checkpoint_path(copy)}..."
          )
          shutil.copyfile(
              self.checkpoint_path(ckpt), self.checkpoint_path(copy)
          )
      logger.info(f"Save Checkpoint finished")
  
imports: import os, shutil
  import sys
  import torch
  from torch import nn
  from torch.nn.parallel.data_parallel import DataParallel
  from openprompt.utils.cuda import model_to_device
  from tensorboardX import SummaryWriter
  from tqdm import tqdm
  import dill
  import warnings
  from typing import Callable, Union, Dict
  from openprompt.pipeline_base import PromptForClassification, PromptForGeneration
  from openprompt import PromptDataLoader
  from openprompt.prompts import *
  from openprompt.utils.logging import logger
  from openprompt.utils.metrics import classification_metrics, generation_metric
  from transformers import AdamW, get_linear_schedule_with_warmup
  from transformers.optimization import Adafactor, AdafactorSchedule
label_desc: Use image node_id 11 for calling the BaseRunner obj's underlying member method code with example usage: obj.save_checkpoint(ckpt, save_state, extra, copy) without return types