code: def main():
      parser = ArgumentParser()
      parser.add_argument(
          "--asr_model",
          type=str,
          required=True,
          help="Path to an ASR model .nemo file or name of a pretrained model.",
      )
      parser.add_argument(
          "--device",
          type=str,
          help="The device to load the model onto and perform the streaming",
          default="cuda",
      )
      parser.add_argument(
          "--audio_file",
          type=str,
          help="Path to an audio file to perform streaming",
          default=None,
      )
      parser.add_argument(
          "--manifest_file",
          type=str,
          help="Path to a manifest file containing audio files to perform streaming",
          default=None,
      )
      parser.add_argument(
          "--use_amp", action="store_true", help="Whether to use AMP"
      )
      parser.add_argument(
          "--debug_mode",
          action="store_true",
          help="Whether to print more detail in the output.",
      )
      parser.add_argument(
          "--compare_vs_offline",
          action="store_true",
          help="Whether to compare the output of the model with the offline mode.",
      )
      parser.add_argument(
          "--batch_size",
          type=int,
          default=32,
          help="The batch size to be used to perform streaming in batch mode with multiple streams",
      )
      parser.add_argument(
          "--chunk_size",
          type=int,
          default=-1,
          help="The chunk_size to be used for models trained with full context and offline models",
      )
      parser.add_argument(
          "--shift_size",
          type=int,
          default=-1,
          help="The shift_size to be used for models trained with full context and offline models",
      )
      parser.add_argument(
          "--left_chunks",
          type=int,
          default=2,
          help="The number of left chunks to be used as left context via caching for offline models",
      )
  
      parser.add_argument(
          "--online_normalization",
          default=False,
          action="store_true",
          help="Perform normalization on the run per chunk.",
      )
      parser.add_argument(
          "--output_path",
          type=str,
          help="path to output file when manifest is used as input",
          default=None,
      )
      parser.add_argument(
          "--pad_and_drop_preencoded",
          action="store_true",
          help="Enables padding the audio input and then dropping the extra steps after the pre-encoding for all the steps including the the first step. It may make the outputs of the downsampling slightly different from offline mode for some techniques like striding or sw_striding.",
      )
  
      parser.add_argument(
          "--set_decoder",
          choices=["ctc", "rnnt"],
          default=None,
          help="Selects the decoder for Hybrid ASR models which has both the CTC and RNNT decoder. Supported decoders are ['ctc', 'rnnt']",
      )
  
      parser.add_argument(
          "--att_context_size",
          type=str,
          default=None,
          help="Sets the att_context_size for the models which support multiple lookaheads",
      )
  
      args = parser.parse_args()
      if (args.audio_file is None and args.manifest_file is None) or (
          args.audio_file is not None and args.manifest_file is not None
      ):
          raise ValueError(
              "One of the audio_file and manifest_file should be non-empty!"
          )
  
      if args.asr_model.endswith(".nemo"):
          logging.info(f"Using local ASR model from {args.asr_model}")
          asr_model = nemo_asr.models.ASRModel.restore_from(
              restore_path=args.asr_model
          )
      else:
          logging.info(f"Using NGC cloud ASR model {args.asr_model}")
          asr_model = nemo_asr.models.ASRModel.from_pretrained(
              model_name=args.asr_model
          )
  
      logging.info(asr_model.encoder.streaming_cfg)
      if args.set_decoder is not None:
          if hasattr(asr_model, "cur_decoder"):
              asr_model.change_decoding_strategy(
                  decoder_type=args.set_decoder
              )
          else:
              raise ValueError(
                  "Decoder cannot get changed for non-Hybrid ASR models."
              )
  
      if args.att_context_size is not None:
          if hasattr(asr_model.encoder, "set_default_att_context_size"):
              asr_model.encoder.set_default_att_context_size(
                  att_context_size=json.loads(args.att_context_size)
              )
          else:
              raise ValueError(
                  "Model does not support multiple lookaheads."
              )
  
      global autocast
      if (
          args.use_amp
          and torch.cuda.is_available()
          and hasattr(torch.cuda, "amp")
          and hasattr(torch.cuda.amp, "autocast")
      ):
          logging.info("AMP enabled!\n")
          autocast = torch.cuda.amp.autocast
      else:
  
          @contextlib.contextmanager
          def autocast():
              yield
  
      # configure the decoding config
      decoding_cfg = asr_model.cfg.decoding
      with open_dict(decoding_cfg):
          decoding_cfg.strategy = "greedy"
          decoding_cfg.preserve_alignments = False
          if hasattr(asr_model, "joint"):  # if an RNNT model
              decoding_cfg.greedy.max_symbols = 10
              decoding_cfg.fused_batch_size = -1
          asr_model.change_decoding_strategy(decoding_cfg)
  
      asr_model = asr_model.to(args.device)
      asr_model.eval()
  
      # chunk_size is set automatically for models trained for streaming. For models trained for offline mode with full context, we need to pass the chunk_size explicitly.
      if args.chunk_size > 0:
          if args.shift_size < 0:
              shift_size = args.chunk_size
          else:
              shift_size = args.shift_size
          asr_model.encoder.setup_streaming_params(
              chunk_size=args.chunk_size,
              left_chunks=args.left_chunks,
              shift_size=shift_size,
          )
  
      # In streaming, offline normalization is not feasible as we don't have access to the whole audio at the beginning
      # When online_normalization is enabled, the normalization of the input features (mel-spectrograms) are done per step
      # It is suggested to train the streaming models without any normalization in the input features.
      if args.online_normalization:
          if asr_model.cfg.preprocessor.normalize not in [
              "per_feature",
              "all_feature",
          ]:
              logging.warning(
                  "online_normalization is enabled but the model has no normalization in the feature extration part, so it is ignored."
              )
              online_normalization = False
          else:
              online_normalization = True
  
      else:
          online_normalization = False
  
      streaming_buffer = CacheAwareStreamingAudioBuffer(
          model=asr_model,
          online_normalization=online_normalization,
          pad_and_drop_preencoded=args.pad_and_drop_preencoded,
      )
      if args.audio_file is not None:
          # stream a single audio file
          (
              processed_signal,
              processed_signal_length,
              stream_id,
          ) = streaming_buffer.append_audio_file(
              args.audio_file, stream_id=-1
          )
          perform_streaming(
              asr_model=asr_model,
              streaming_buffer=streaming_buffer,
              compare_vs_offline=args.compare_vs_offline,
              pad_and_drop_preencoded=args.pad_and_drop_preencoded,
          )
      else:
          # stream audio files in a manifest file in batched mode
          samples = []
          all_streaming_tran = []
          all_offline_tran = []
          all_refs_text = []
  
          with open(args.manifest_file, "r") as f:
              for line in f:
                  item = json.loads(line)
                  samples.append(item)
  
          logging.info(
              f"Loaded {len(samples)} from the manifest at {args.manifest_file}."
          )
  
          start_time = time.time()
          for sample_idx, sample in enumerate(samples):
              (
                  processed_signal,
                  processed_signal_length,
                  stream_id,
              ) = streaming_buffer.append_audio_file(
                  sample["audio_filepath"], stream_id=-1
              )
              if "text" in sample:
                  all_refs_text.append(sample["text"])
              logging.info(
                  f'Added this sample to the buffer: {sample["audio_filepath"]}'
              )
  
              if (
                  sample_idx + 1
              ) % args.batch_size == 0 or sample_idx == len(
                  samples
              ) - 1:
                  logging.info(
                      f"Starting to stream samples {sample_idx - len(streaming_buffer) + 1} to {sample_idx}..."
                  )
                  streaming_tran, offline_tran = perform_streaming(
                      asr_model=asr_model,
                      streaming_buffer=streaming_buffer,
                      compare_vs_offline=args.compare_vs_offline,
                      debug_mode=args.debug_mode,
                      pad_and_drop_preencoded=args.pad_and_drop_preencoded,
                  )
                  all_streaming_tran.extend(streaming_tran)
                  if args.compare_vs_offline:
                      all_offline_tran.extend(offline_tran)
                  streaming_buffer.reset_buffer()
  
          if args.compare_vs_offline and len(all_refs_text) == len(
              all_offline_tran
          ):
              offline_wer = word_error_rate(
                  hypotheses=all_offline_tran, references=all_refs_text
              )
              logging.info(
                  f"WER% of offline mode: {round(offline_wer * 100, 2)}"
              )
          if len(all_refs_text) == len(all_streaming_tran):
              streaming_wer = word_error_rate(
                  hypotheses=all_streaming_tran,
                  references=all_refs_text,
              )
              logging.info(
                  f"WER% of streaming mode: {round(streaming_wer*100, 2)}"
              )
  
          end_time = time.time()
          logging.info(
              f"The whole streaming process took: {round(end_time - start_time, 2)}s"
          )
  
          # stores the results including the transcriptions of the streaming inference in a json file
          if args.output_path is not None and len(all_refs_text) == len(
              all_streaming_tran
          ):
              fname = (
                  "streaming_out_"
                  + os.path.splitext(os.path.basename(args.asr_model))[
                      0
                  ]
                  + "_"
                  + os.path.splitext(
                      os.path.basename(args.test_manifest)
                  )[0]
                  + ".json"
              )
  
              hyp_json = os.path.join(args.output_path, fname)
              os.makedirs(args.output_path, exist_ok=True)
              with open(hyp_json, "w") as out_f:
                  for i, hyp in enumerate(all_streaming_tran):
                      record = {
                          "pred_text": hyp,
                          "text": all_refs_text[i],
                          "wer": round(
                              word_error_rate(
                                  hypotheses=[hyp],
                                  references=[all_refs_text[i]],
                              )
                              * 100,
                              2,
                          ),
                      }
                      out_f.write(json.dumps(record) + "\n")
  
file_path: NeMo/examples/asr/asr_cache_aware_streaming/speech_to_text_cache_aware_streaming_infer.py
imports: import contextlib
  import json
  import os
  import time
  from argparse import ArgumentParser
  import torch
  from omegaconf import open_dict
  import nemo.collections.asr
  from nemo.collections.asr.metrics.wer import word_error_rate
  from nemo.collections.asr.parts.utils.rnnt_utils import Hypothesis
  from nemo.collections.asr.parts.utils.streaming_utils import CacheAwareStreamingAudioBuffer
  from nemo.utils import logging
label_desc: Use image node_id 4 for calling a global function with example usage: main() without return types