code: def evaluation(model, args, tokenizer, loss_func):
      bmt.print_rank("evaluation begins...")
      eval_dataloader = FinetuneDataset(
          args.eval_dataset,
          1,
          args.max_length,
          tokenizer,
          max_depth=8,
          task_name=args.task_name,
          drop_last=args.drop_last,
      )
      eval_losses = []
      last_data = None
      with torch.no_grad():
          for iteration, data in enumerate(eval_dataloader):
              iteration = iteration + 1
              skip_this_batch = False
              if data is None:
                  if last_data is None:
                      raise RuntimeError(
                          "Dataset is too small, please use a smaller batch size or sequence length!"
                      )
                  data = last_data
                  skip_this_batch = True
              else:
                  last_data = data
  
              input_ids = (
                  torch.from_numpy(data["inputs"])
                  .cuda()
                  .to(torch.int32)
              )
              input_ids_sub = (
                  torch.from_numpy(data["inputs_sub"])
                  .cuda()
                  .to(torch.int32)
              )
              input_length = (
                  torch.from_numpy(data["length"])
                  .cuda()
                  .to(torch.int32)
              )
              input_context = (
                  torch.from_numpy(data["context"]).cuda().bool()
              )
              input_sample_ids = (
                  torch.from_numpy(data["sample_ids"])
                  .cuda()
                  .to(torch.int32)
              )
              input_num_segments = (
                  torch.from_numpy(data["num_segments"])
                  .cuda()
                  .to(torch.int32)
              )
              input_segment_ids = (
                  torch.from_numpy(data["segment_ids"])
                  .cuda()
                  .to(torch.int32)
              )
              input_segment_rel_offset = (
                  torch.from_numpy(data["segment_rel_offset"])
                  .cuda()
                  .to(torch.int32)
              )
              input_segment_rel = (
                  torch.from_numpy(data["segment_rel"])
                  .cuda()
                  .to(torch.int32)
              )
              input_span = (
                  torch.from_numpy(data["spans"]).cuda().to(torch.int32)
              )
              targets = (
                  torch.from_numpy(data["target"])
                  .cuda()
                  .to(torch.int32)
              )
              ext_table_ids = (
                  torch.from_numpy(data["ext_ids"])
                  .cuda()
                  .to(torch.int32)
              )
              ext_table_sub = (
                  torch.from_numpy(data["ext_sub"])
                  .cuda()
                  .to(torch.int32)
              )
              # ===========
              mem_usage = {}
              tim_usage = {}
              mem_usage, tim_usage = add_mem_time(
                  "init", mem_usage, tim_usage
              )
  
              # ===========
              logits, _ = model(
                  input_ids,
                  input_ids_sub,
                  input_length,
                  input_context,
                  input_sample_ids,
                  input_num_segments,
                  input_segment_ids,
                  input_segment_rel_offset,
                  input_segment_rel,
                  input_span,
                  ext_table_ids,
                  ext_table_sub,
              )
  
              loss = loss_func(
                  logits.view(-1, logits.size(-1)), targets.view(-1)
              )
              if skip_this_batch:
                  loss = loss * 0
              eval_losses.append(bmt.sum_loss(loss))
  
          overall_loss = torch.stack(eval_losses).mean().item()
      return overall_loss
  
imports: import time
  from typing import Dict, List, Union
  import torch
  import bmtrain
  import os
  from opendelta import LoraModel
  from cpm_live.arguments import get_args
  from cpm_live.models import CPMBee, CPMBeeConfig
  from cpm_live.tokenizers import CPMBeeTokenizer
  from cpm_live.utils import allgather_objects
  from cpm_live.training_tasks.bee import FinetuneDataset
label_desc: Use image node_id 9 for calling a global function with example usage: evaluation(model, args, tokenizer, loss_func) and returns: overall_loss