code: def main(cmd_args):
      """Train LM."""
      parser = get_parser()
      args, _ = parser.parse_known_args(cmd_args)
      if args.backend == "chainer" and args.train_dtype != "float32":
          raise NotImplementedError(
              f"chainer backend does not support --train-dtype {args.train_dtype}."
              "Use --dtype float32."
          )
      if args.ngpu == 0 and args.train_dtype in (
          "O0",
          "O1",
          "O2",
          "O3",
          "float16",
      ):
          raise ValueError(
              f"--train-dtype {args.train_dtype} does not support the CPU backend."
          )
  
      # parse arguments dynamically
      model_class = dynamic_import_lm(args.model_module, args.backend)
      model_class.add_arguments(parser)
      if args.schedulers is not None:
          for k, v in args.schedulers:
              scheduler_class = dynamic_import_scheduler(v)
              scheduler_class.add_arguments(k, parser)
  
      opt_class = dynamic_import_optimizer(args.opt, args.backend)
      opt_class.add_arguments(parser)
  
      args = parser.parse_args(cmd_args)
  
      # add version info in args
      args.version = __version__
  
      # logging info
      if args.verbose > 0:
          logging.basicConfig(
              level=logging.INFO,
              format="%(asctime)s (%(module)s:%(lineno)d) %(levelname)s: %(message)s",
          )
      else:
          logging.basicConfig(
              level=logging.WARN,
              format="%(asctime)s (%(module)s:%(lineno)d) %(levelname)s: %(message)s",
          )
          logging.warning("Skip DEBUG/INFO messages")
  
      # If --ngpu is not given,
      #   1. if CUDA_VISIBLE_DEVICES is set, all visible devices
      #   2. if nvidia-smi exists, use all devices
      #   3. else ngpu=0
      if args.ngpu is None:
          cvd = os.environ.get("CUDA_VISIBLE_DEVICES")
          if cvd is not None:
              ngpu = len(cvd.split(","))
          else:
              logging.warning("CUDA_VISIBLE_DEVICES is not set.")
              try:
                  p = subprocess.run(
                      ["nvidia-smi", "-L"],
                      stdout=subprocess.PIPE,
                      stderr=subprocess.PIPE,
                  )
              except (subprocess.CalledProcessError, FileNotFoundError):
                  ngpu = 0
              else:
                  ngpu = len(p.stderr.decode().split("\n")) - 1
          args.ngpu = ngpu
      else:
          ngpu = args.ngpu
      logging.info(f"ngpu: {ngpu}")
  
      # display PYTHONPATH
      logging.info(
          "python path = " + os.environ.get("PYTHONPATH", "(None)")
      )
  
      # seed setting
      nseed = args.seed
      random.seed(nseed)
      np.random.seed(nseed)
  
      # load dictionary
      with open(args.dict, "rb") as f:
          dictionary = f.readlines()
      char_list = [
          entry.decode("utf-8").split(" ")[0] for entry in dictionary
      ]
      char_list.insert(0, "<blank>")
      char_list.append("<eos>")
      args.char_list_dict = {x: i for i, x in enumerate(char_list)}
      args.n_vocab = len(char_list)
  
      # train
      logging.info("backend = " + args.backend)
      if args.backend == "chainer":
          from espnet.lm.chainer_backend.lm import train
  
          train(args)
      elif args.backend == "pytorch":
          from espnet.lm.pytorch_backend.lm import train
  
          train(args)
      else:
          raise ValueError("Only chainer and pytorch are supported.")
  
file_path: espnet/espnet/bin/lm_train.py
imports: import logging
  import os
  import random
  import subprocess
  import sys
  import configargparse
  import numpy
  from espnet import __version__
  from espnet.nets.lm_interface import dynamic_import_lm
  from espnet.optimizer.factory import dynamic_import_optimizer
  from espnet.scheduler.scheduler import dynamic_import_scheduler
label_desc: Use image node_id 2 for calling a global function with example usage: main(cmd_args) without return types