code: def get_bleu(produced_tokens, target_tokens, tgt_dict):
      assert target_tokens.ndim == 1
      assert produced_tokens.size(1) == target_tokens.size(0)
  
      # we can have padding due to shifted channels
      shift = 0
      for token in reversed(target_tokens.cpu().tolist()):
          if token in [tgt_dict.pad(), tgt_dict.eos()]:
              shift += 1
          else:
              break
      target_tokens = target_tokens[:-shift]
      produced_tokens = produced_tokens[:, :-shift]
  
      string_target = tgt_dict.string(target_tokens).split()
      string_candidates = [
          tgt_dict.string(produced_tokens[i, :]).split()
          for i in range(produced_tokens.size(0))
      ]
  
      bleu3 = sentence_bleu(
          references=string_candidates,
          hypothesis=string_target,
          weights=(1.0 / 3, 1.0 / 3, 1.0 / 3),
      )
      return bleu3
  
imports: import os
  import numpy
  import scipy
  import torch
  import torch.multiprocessing
  from fairseq import checkpoint_utils, options
  from fairseq.data.codedataset import CodeDataset, ExpressiveCodeDataConfig
  from fairseq.dataclass.utils import convert_namespace_to_omegaconf
  from torch.utils.data import DataLoader, DistributedSampler
  from fairseq.utils import move_to_cuda
  from fairseq import utils
  from fairseq.criterions.speech_ulm_criterion import nll_loss, mae_loss
  import time
  from types import SimpleNamespace
  import sys, pathlib
  from naive_decoder import Naive_F0_Decoder
  from inference_dataset import InferenceDataset, explode_batch
  from sample.sample import do_sampling, TemperatureDecoder, FilterNamesDataset
label_desc: Use image node_id 2 for calling a global function with example usage: get_bleu(produced_tokens, target_tokens, tgt_dict) and returns: bleu3