code: def run_eval(args: EvalArguments):
      torch_dtype = torch.float16
  
      seed = 2
      torch.manual_seed(seed)
      random.seed(seed)
      np.random.seed(seed)
  
      dataset = Pg19Dataset(
          args.data_path, seq_length=args.seq_len, sliding_window=256
      )
      if args.flash_attn:
          replace_llama_attn(use_flash_attn=True, use_full=True)
  
      # Set RoPE scaling factor
      config = transformers.AutoConfig.from_pretrained(
          args.base_model, cache_dir=args.cache_dir, use_cache=False
      )
  
      context_size = (
          args.context_size if args.context_size > 0 else args.seq_len
      )
      orig_ctx_len = getattr(
          config, "max_position_embeddings", None
      )  # this value should be 4096 for LLaMA2 models
      if orig_ctx_len and context_size > orig_ctx_len:
          scaling_factor = float(math.ceil(context_size / orig_ctx_len))
          config.rope_scaling = {
              "type": "linear",
              "factor": scaling_factor,
          }
  
      # Load model and tokenizer
      model = transformers.AutoModelForCausalLM.from_pretrained(
          args.base_model,
          config=config,
          cache_dir=args.cache_dir,
          torch_dtype=torch_dtype,
      )
      model.resize_token_embeddings(32001)
  
      if args.peft_model:
          trainable_params = os.path.join(
              args.peft_model, "trainable_params.bin"
          )
          if os.path.isfile(trainable_params):
              model.load_state_dict(
                  torch.load(
                      trainable_params, map_location=model.device
                  ),
                  strict=False,
              )
          else:
              raise ValueError(
                  "Trainable input embedding and normalization are required."
              )
          model = PeftModel.from_pretrained(
              model,
              args.peft_model,
              torch_dtype=torch_dtype,
              offload_folder=args.cache_dir,
          )
  
      # This is a hacky way to enable distributed evaluation. Otherwise, without any trainable parameters, we will not
      # be able to use DistributedDataParallel, although we don't update any parameters during evaluation.
      [
          p.requires_grad_()
          for n, p in model.named_parameters()
          if any([k in n for k in ["lm_head"]])
      ]
  
      gpu_id = int(os.environ["LOCAL_RANK"])
      model.to(gpu_id)
  
      evaluator = DistributedEvaluator(
          model=model,
          batch_size=args.batch_size,
          refresh_rate=args.progress_bar_fresh_rate,
          gpu_id=gpu_id,
      )
  
      if evaluator.is_first_device():
          print("data path", args.data_path)
          print("base model", args.base_model)
          print("peft model", args.peft_model)
          print(
              f"Num validation tokens: {dataset.num_tokens()}, Num validation examples: {len(dataset)}"
          )
  
      eval_metric = EvalMetricImpl(
          vocab_size=config.vocab_size, gpu_id=gpu_id
      )
      result = evaluator.evaluate(dataset, eval_metric)
      if evaluator.is_first_device():
          print(result)
  
imports: import os
  from dataclasses import dataclass, field
  from typing import Optional
  import math
  import random
  import transformers
  from peft import PeftModel
  from llama_attn_replace import replace_llama_attn
  from torch.distributed import init_process_group, destroy_process_group
  from torchmetrics import Accuracy
  from torchmetrics.text import Perplexity
  from torch.nn import CrossEntropyLoss
  import inspect
  from abc import ABC, abstractmethod
  from typing import Union
  from torch.utils.data import Dataset, DataLoader, DistributedSampler
  from transformers.modeling_utils import PreTrainedModel
  from torch import nn
  from torch.nn.parallel import DistributedDataParallel
  from tqdm import tqdm
  import numpy
  import torch
label_desc: Use image node_id 1 for calling a global function with example usage: run_eval(args) without return types