code: def extract_embed(args):
      distributed_option = build_dataclass(DistributedOption, args)
      distributed_option.init_options()
  
      if (
          not distributed_option.distributed
          or distributed_option.dist_rank == 0
      ):
          if not distributed_option.distributed:
              _rank = ""
          else:
              _rank = (
                  f":{distributed_option.dist_rank}/"
                  f"{distributed_option.dist_world_size}"
              )
  
          logging.basicConfig(
              level=args.log_level,
              format=f"[{os.uname()[1].split('.')[0]}{_rank}]"
              f" %(asctime)s (%(module)s:%(lineno)d) %(levelname)s: %(message)s",
          )
      else:
          # Suppress logging if RANK != 0
          logging.basicConfig(
              level="ERROR",
              format=f"[{os.uname()[1].split('.')[0]}"
              f":{distributed_option.dist_rank}/{distributed_option.dist_world_size}]"
              f" %(asctime)s (%(module)s:%(lineno)d) %(levelname)s: %(message)s",
          )
      # Invoking torch.distributed.init_process_group
      distributed_option.init_torch_distributed()
  
      logging.basicConfig(
          level=args.log_level,
          format="%(asctime)s (%(module)s:%(lineno)d) %(levelname)s: %(message)s",
      )
  
      if args.ngpu >= 1:
          device = "cuda"
      else:
          device = "cpu"
  
      # 1. Set random-seed
      set_all_random_seed(args.seed)
  
      # 2. define train args
      spk_model, spk_train_args = SpeakerTask.build_model_from_file(
          args.spk_train_config, args.spk_model_file, device
      )
  
      # 3. Overwrite args with inference args
      args = vars(args)
      args["valid_data_path_and_name_and_type"] = args[
          "data_path_and_name_and_type"
      ]
      args["valid_shape_file"] = args["shape_file"]
      args["preprocessor_conf"] = {
          "target_duration": args["target_duration"],
          "num_eval": args["num_eval"],
          "noise_apply_prob": 0.0,
          "rir_apply_prob": 0.0,
      }
  
      merged_args = vars(spk_train_args)
      merged_args.update(args)
      args = argparse.Namespace(**merged_args)
  
      # 4. Build data-iterator
      # NOTE(jeeweon): Temporarily disable distributed to let loader include all trials
      org_distributed = distributed_option.distributed
      distributed_option.distributed = False
      iterator = SpeakerTask.build_iter_factory(
          args=args,
          distributed_option=distributed_option,
          mode="valid",
      )
      distributed_option.distributed = org_distributed
      loader = iterator.build_iter(0)
      bs = (
          args.valid_batch_size // args.ngpu
          if distributed_option.distributed
          else args.valid_batch_size
      )
  
      trainer_options = SpeakerTask.trainer.build_options(args)
      reporter = Reporter()
  
      # 5. Run inference for EER and minDCF calculation
      with reporter.observe("valid") as sub_reporter:
          SpeakerTask.trainer.extract_embed(
              model=spk_model,
              iterator=loader,
              reporter=sub_reporter,
              options=trainer_options,
              distributed_option=distributed_option,
              output_dir=args.output_dir,
              custom_bs=bs,
              average=args.average_embd,
          )
  
      if distributed_option.distributed:
          torch.distributed.barrier()
      if (
          not distributed_option.distributed
          or distributed_option.dist_rank == 0
      ):
          # Combine dictionaries into one
          npzs = glob(args.output_dir + "/embeddings*.npz")
          logging.info(f"{npzs}")
          embd_dic = {}
          for npz in npzs:
              tmp_dic = dict(np.load(npz))
              embd_dic.update(tmp_dic)
          set_name = args.data_path_and_name_and_type[0][0].split("/")[
              -2
          ]
          np.savez(
              args.output_dir + f"/{set_name}_embeddings", **embd_dic
          )
          for npz in npzs:
              os.remove(npz)
  
imports: import argparse
  import logging
  import os
  import sys
  from glob import glob
  import humanfriendly
  import numpy
  import torch
  from torch.multiprocessing.spawn import ProcessContext
  from typeguard import check_argument_types, check_return_type
  from espnet2.samplers.build_batch_sampler import BATCH_TYPES
  from espnet2.tasks.spk import SpeakerTask
  from espnet2.torch_utils.set_all_random_seed import set_all_random_seed
  from espnet2.train.distributed_utils import DistributedOption, free_port, get_master_port, get_node_rank, get_num_nodes, resolve_distributed_mode
  from espnet2.train.reporter import Reporter, SubReporter
  from espnet2.utils import config_argparse
  from espnet2.utils.build_dataclass import build_dataclass
  from espnet2.utils.nested_dict_action import NestedDictAction
  from espnet2.utils.types import humanfriendly_parse_size_or_none, int_or_none, str2bool, str2triple_str, str_or_none
  from espnet.utils.cli_utils import get_commandline_args
label_desc: Use image node_id 1 for calling a global function with example usage: extract_embed(args) without return types