code: def train_and_evaluate(model, params, ex_params, restore_file=""):
      """Train the model and evaluate every epoch."""
      # Load training data and val data
      dataloader = CustomDataLoader(params)
      train_loader = dataloader.get_dataloader(
          data_sign="train", ex_params=ex_params
      )
      val_loader = dataloader.get_dataloader(
          data_sign="val", ex_params=ex_params
      )
      # reload weights from restore_file if specified
      if restore_file != "":
          restore_path = os.path.join(
              params.model_dir, params.restore_file + ".pth.tar"
          )
          logging.info(
              "Restoring parameters from {}".format(restore_path)
          )
          # 读取checkpoint
          model, optimizer = util.load_checkpoint(restore_path)
  
      model.to(params.device)
      # wandb.watch(model, log="all")
      # parallel model
      if params.n_gpu > 1 and params.multi_gpu:
          model = torch.nn.DataParallel(model)
  
      # Prepare optimizer
      # fine-tuning
      param_optimizer = list(model.named_parameters())
      # pretrain model param
      param_pre = [(n, p) for n, p in param_optimizer if "bert" in n]
      # downstream model param
      param_downstream = [
          (n, p) for n, p in param_optimizer if "bert" not in n
      ]
      no_decay = ["bias", "LayerNorm", "layer_norm"]
      optimizer_grouped_parameters = [
          # pretrain model param
          {
              "params": [
                  p
                  for n, p in param_pre
                  if not any(nd in n for nd in no_decay)
              ],
              "weight_decay": params.weight_decay_rate,
              "lr": params.fin_tuning_lr,
          },
          {
              "params": [
                  p
                  for n, p in param_pre
                  if any(nd in n for nd in no_decay)
              ],
              "weight_decay": 0.0,
              "lr": params.fin_tuning_lr,
          },
          # downstream model
          {
              "params": [
                  p
                  for n, p in param_downstream
                  if not any(nd in n for nd in no_decay)
              ],
              "weight_decay": params.weight_decay_rate,
              "lr": params.downs_en_lr,
          },
          {
              "params": [
                  p
                  for n, p in param_downstream
                  if any(nd in n for nd in no_decay)
              ],
              "weight_decay": 0.0,
              "lr": params.downs_en_lr,
          },
      ]
      num_train_optimization_steps = (
          len(train_loader)
          // params.gradient_accumulation_steps
          * params.epoch_num
      )
      optimizer = BertAdam(
          optimizer_grouped_parameters,
          warmup=params.warmup_prop,
          schedule="warmup_cosine",
          t_total=num_train_optimization_steps,
          max_grad_norm=params.clip_grad,
      )
  
      # patience stage
      best_val_f1 = 0.0
      patience_counter = 0
  
      for epoch in range(1, params.epoch_num + 1):
          # Run one epoch
          logging.info("Epoch {}/{}".format(epoch, params.epoch_num))
  
          # Train for one epoch on training set
          train(model, train_loader, optimizer, params, ex_params)
  
          # Evaluate for one epoch on training set and validation set
          # train_metrics = evaluate(args, model, train_loader, params, mark='Train',
          #                          verbose=True)  # Dict['loss', 'f1']
          val_metrics, _, _ = evaluate(
              model, val_loader, params, ex_params, mark="Val"
          )
          val_f1 = val_metrics["f1"]
          improve_f1 = val_f1 - best_val_f1
  
          # Save weights of the network
          model_to_save = (
              model.module if hasattr(model, "module") else model
          )  # Only save the model it-self
          optimizer_to_save = optimizer
          util.save_checkpoint(
              {
                  "epoch": epoch + 1,
                  "model": model_to_save,
                  "optim": optimizer_to_save,
              },
              is_best=improve_f1 > 0,
              checkpoint=params.model_dir,
          )
          params.save(os.path.join(params.ex_dir, "params.json"))
  
          # stop training based params.patience
          if improve_f1 > 0:
              logging.info("- Found new best F1")
              best_val_f1 = val_f1
              if improve_f1 < params.patience:
                  patience_counter += 1
              else:
                  patience_counter = 0
          else:
              patience_counter += 1
  
          # Early stopping and logging best f1
          if (
              patience_counter > params.patience_num
              and epoch > params.min_epoch_num
          ) or epoch == params.epoch_num:
              logging.info("Best val f1: {:05.2f}".format(best_val_f1))
              break
  
          wandb.log(
              {
                  "best_val_f1": best_val_f1,
              }
          )
  
file_path: DeepKE/example/triple/PRGC/run.py
imports: import os
  import hydra
  from hydra.utils import get_original_cwd
  import torch
  from transformers import BertConfig
  import random
  import logging
  from tqdm import trange
  import argparse
  import wandb
  from deepke.triple_extraction.PRGC import *
label_desc: Use image node_id 2 for calling a global function with example usage: train_and_evaluate(model, params, ex_params, restore_file) without return types