code: def decoding_step(
      model: nemo_asr.models.ASRModel,
      cfg: EvalBeamSearchNGramConfig,
      all_probs: List[torch.Tensor],
      target_transcripts: List[str],
      preds_output_file: str = None,
      beam_batch_size: int = 128,
      progress_bar: bool = True,
  ):
      level = logging.getEffectiveLevel()
      logging.setLevel(logging.CRITICAL)
      # Reset config
      model.change_decoding_strategy(None)
  
      cfg.decoding.hat_ilm_weight = (
          cfg.decoding.hat_ilm_weight * cfg.hat_subtract_ilm
      )
      # Override the beam search config with current search candidate configuration
      cfg.decoding.return_best_hypothesis = False
      cfg.decoding.ngram_lm_model = cfg.kenlm_model_file
      cfg.decoding.hat_subtract_ilm = cfg.hat_subtract_ilm
  
      # Update model's decoding strategy config
      model.cfg.decoding.strategy = cfg.decoding_strategy
      model.cfg.decoding.beam = cfg.decoding
  
      # Update model's decoding strategy
      model.change_decoding_strategy(model.cfg.decoding)
      logging.setLevel(level)
  
      wer_dist_first = cer_dist_first = 0
      wer_dist_best = cer_dist_best = 0
      words_count = 0
      chars_count = 0
      sample_idx = 0
      if preds_output_file:
          out_file = open(
              preds_output_file, "w", encoding="utf_8", newline="\n"
          )
  
      if progress_bar:
          if cfg.decoding_strategy == "greedy_batch":
              description = "Greedy_batch decoding.."
          else:
              description = f"{cfg.decoding_strategy} decoding with bw={cfg.decoding.beam_size}, ba={cfg.decoding.ngram_lm_alpha}, ma={cfg.decoding.maes_prefix_alpha}, mg={cfg.decoding.maes_expansion_gamma}, hat_ilmw={cfg.decoding.hat_ilm_weight}"
          it = tqdm(
              range(int(np.ceil(len(all_probs) / beam_batch_size))),
              desc=description,
              ncols=120,
          )
      else:
          it = range(int(np.ceil(len(all_probs) / beam_batch_size)))
      for batch_idx in it:
          # disabling type checking
          probs_batch = all_probs[
              batch_idx
              * beam_batch_size : (batch_idx + 1)
              * beam_batch_size
          ]
          probs_lens = torch.tensor(
              [prob.shape[-1] for prob in probs_batch]
          )
          with torch.no_grad():
              packed_batch = torch.zeros(
                  len(probs_batch),
                  probs_batch[0].shape[0],
                  max(probs_lens),
                  device="cpu",
              )
  
              for prob_index in range(len(probs_batch)):
                  packed_batch[
                      prob_index, :, : probs_lens[prob_index]
                  ] = torch.tensor(
                      probs_batch[prob_index].unsqueeze(0),
                      device=packed_batch.device,
                      dtype=packed_batch.dtype,
                  )
              (
                  best_hyp_batch,
                  beams_batch,
              ) = model.decoding.rnnt_decoder_predictions_tensor(
                  packed_batch,
                  probs_lens,
                  return_hypotheses=True,
              )
          if cfg.decoding_strategy == "greedy_batch":
              beams_batch = [[x] for x in best_hyp_batch]
  
          for beams_idx, beams in enumerate(beams_batch):
              target = target_transcripts[sample_idx + beams_idx]
              target_split_w = target.split()
              target_split_c = list(target)
              words_count += len(target_split_w)
              chars_count += len(target_split_c)
              wer_dist_min = cer_dist_min = 10000
              for candidate_idx, candidate in enumerate(
                  beams
              ):  # type: (int, rnnt_beam_decoding.rnnt_utils.Hypothesis)
                  pred_text = candidate.text
                  pred_split_w = pred_text.split()
                  wer_dist = editdistance.eval(
                      target_split_w, pred_split_w
                  )
                  pred_split_c = list(pred_text)
                  cer_dist = editdistance.eval(
                      target_split_c, pred_split_c
                  )
  
                  wer_dist_min = min(wer_dist_min, wer_dist)
                  cer_dist_min = min(cer_dist_min, cer_dist)
  
                  if candidate_idx == 0:
                      # first candidate
                      wer_dist_first += wer_dist
                      cer_dist_first += cer_dist
  
                  score = candidate.score
                  if preds_output_file:
                      out_file.write(
                          "{}\t{}\n".format(pred_text, score)
                      )
              wer_dist_best += wer_dist_min
              cer_dist_best += cer_dist_min
          sample_idx += len(probs_batch)
  
      if cfg.decoding_strategy == "greedy_batch":
          return (
              wer_dist_first / words_count,
              cer_dist_first / chars_count,
          )
  
      if preds_output_file:
          out_file.close()
          logging.info(
              f"Stored the predictions of {cfg.decoding_strategy} decoding at '{preds_output_file}'."
          )
  
      if cfg.decoding.ngram_lm_model:
          logging.info(
              f"WER/CER with {cfg.decoding_strategy} decoding and N-gram model = {wer_dist_first / words_count:.2%}/{cer_dist_first / chars_count:.2%}"
          )
      else:
          logging.info(
              f"WER/CER with {cfg.decoding_strategy} decoding = {wer_dist_first / words_count:.2%}/{cer_dist_first / chars_count:.2%}"
          )
      logging.info(
          f"Oracle WER/CER in candidates with perfect LM= {wer_dist_best / words_count:.2%}/{cer_dist_best / chars_count:.2%}"
      )
      logging.info(
          f"================================================================================="
      )
  
      return wer_dist_first / words_count, cer_dist_first / chars_count
  
imports: import contextlib
  import json
  import os
  import pickle
  import tempfile
  from dataclasses import dataclass, field, is_dataclass
  from pathlib import Path
  from typing import List, Optional
  import editdistance
  import numpy
  import torch
  from omegaconf import MISSING, OmegaConf
  from sklearn.model_selection import ParameterGrid
  from tqdm.auto import tqdm
  import nemo.collections.asr
  from nemo.collections.asr.parts.submodules import rnnt_beam_decoding
  from nemo.core.config import hydra_runner
  from nemo.utils import logging
label_desc: Use image node_id 1 for calling a global function with example usage: decoding_step(model, cfg, all_probs, target_transcripts, preds_output_file, beam_batch_size, progress_bar) and returns: unknown,  unknown, unknown,  unknown