






import argparse
import dataclasses
import json
import logging
import os
import shutil
from typing import List, Optional

import datasets
from accelerate import Accelerator
from datasets import load_dataset
from finetuning import finetune
from tqdm.auto import tqdm

import transformers
from transformers import AutoConfig, set_seed
from transformers.trainer_utils import IntervalStrategy


a		:       Optional[int]			     = logging.getLogger(__name__)

a		:       str			     = "pytorch_model.bin"
@dataclasses.dataclass
class     a    :



      """simple docstring"""


      a  : str							       =	dataclasses.field(
          metadata={'help': 'Path to pretrained model or model identifier from huggingface.co/models.'}   )
      a  : Optional[str]							       =	dataclasses.field(
          default=lowercase__							,       metadata={'help': 'Where do you want to store the pretrained models downloaded from huggingface.co.'}							,       )


@dataclasses.dataclass
class     a    :



      """simple docstring"""


      a  : str							       =	dataclasses.field(metadata={'help': 'A csv or a json file containing the training data.'}   )
      a  : str							       =	dataclasses.field(metadata={'help': 'A csv or a json file containing the data to predict on.'}   )
      a  : Optional[str]							       =	dataclasses.field(
          default=lowercase__							,       metadata={'help': 'A csv or a json file containing the validation data.'}   )
      a  : Optional[str]							       =	dataclasses.field(
          default=lowercase__							,       metadata={'help': 'The name of the task to train on.'}							,       )
      a  : Optional[List[str]]							       =	dataclasses.field(
          default=lowercase__							,       metadata={'help': 'The list of labels for the task.'}   )


@dataclasses.dataclass
class     a    :



      """simple docstring"""


      a  : str							       =	dataclasses.field(
          metadata={'help': 'The output directory where the model predictions and checkpoints will be written.'}   )
      a  : Optional[str]							       =	dataclasses.field(
          default='accuracy'							,       metadata={'help': 'The evaluation metric used for the task.'}   )
      a  : Optional[str]							       =	dataclasses.field(
          default='no'							,       metadata={
              'help': 'The evaluation strategy to adopt during training. Possible values are: ["no", "step", "epoch]'
          }							,       )
      a  : Optional[int]							       =	dataclasses.field(
          default=10							,       metadata={'help': 'Number of evaluation calls with no improvement after which training will be stopped.'}							,       )
      a  : Optional[float]							       =	dataclasses.field(
          default=0.0							,       metadata={
              'help': 'How much the specified evaluation metric must improve to satisfy early stopping conditions.'
          }							,       )
      a  : Optional[bool]							       =	dataclasses.field(
          default=lowercase__							,       metadata={'help': 'Whether to filter the pseudo-labeled data based on the confidence score.'}							,       )
      a  : Optional[bool]							       =	dataclasses.field(
          default=lowercase__							,       metadata={'help': 'Whether to filter the pseudo-labeled data based on the validation performance.'}							,       )
      a  : Optional[bool]							       =	dataclasses.field(
          default=lowercase__							,       metadata={'help': 'Whether to fine-tune on labeled data after pseudo training.'}							,       )
      a  : Optional[float]							       =	dataclasses.field(
          default=0.0							,       metadata={'help': 'Confidence threshold for pseudo-labeled data filtering.'}							,       )
      a  : Optional[int]							       =	dataclasses.field(
          default=100							,       metadata={'help': 'Number of evaluation calls with no improvement after which training will be stopped.'}							,       )
      a  : Optional[int]							       =	dataclasses.field(
          default=lowercase__							,       metadata={'help': 'Random seed for initialization.'}							,       )






def 				lowerCamelCase__      (    __lowerCamelCase			:     Optional[int]  ,		__lowerCamelCase			:     Optional[int]  ,		__lowerCamelCase			:     Tuple  ,		__lowerCamelCase			:     Optional[Any]  ,		__lowerCamelCase			:     List[str]  ,		__lowerCamelCase			:     str		):
  __UpperCAmelCase							:	List[str]           =  datasets.concatenate_datasets([infer_input, infer_output]  ,		axis=1		)

  if args.do_filter_by_confidence:
    __UpperCAmelCase							:	Dict           =  dataset.filter(lambda __lowerCamelCase		: example["probability"] > args.confidence_threshold		)

  if args.do_filter_by_val_performance:
    assert eval_result >= 0.0 and eval_result <= 1.0
    __UpperCAmelCase							:	Union[str, Any]           =  int(eval_result * len(__lowerCamelCase		)		)
    print(__lowerCamelCase		)
    __UpperCAmelCase							:	int           =  dataset.sort("""probability"""  ,		reverse=__lowerCamelCase		)
    __UpperCAmelCase							:	Optional[Any]           =  dataset.select(range(__lowerCamelCase		)		)

  __UpperCAmelCase							:	Optional[Any]           =  dataset.remove_columns(["""label""", """probability"""]		)
  __UpperCAmelCase							:	Any           =  dataset.rename_column("""prediction"""  ,		"""label"""		)
  __UpperCAmelCase							:	Union[str, Any]           =  dataset.map(lambda __lowerCamelCase		: {"label": idalabel[example["label"]]}		)
  __UpperCAmelCase							:	List[Any]           =  dataset.shuffle(seed=args.seed		)

  __UpperCAmelCase							:	Tuple           =  os.path.join(__lowerCamelCase  ,		f"""train_pseudo.{args.data_file_extension}"""		)
  if args.data_file_extension == "csv":
    dataset.to_csv(__lowerCamelCase  ,		index=__lowerCamelCase		)
  else:
    dataset.to_json(__lowerCamelCase		)







def 				lowerCamelCase__      (    __lowerCamelCase			:     List[str]  ,		__lowerCamelCase			:     Dict  ,		__lowerCamelCase			:     Any  ,		__lowerCamelCase			:     Dict  ,		**__lowerCamelCase			:     Union[str, Any]		):
  __UpperCAmelCase							:	Dict           =  Accelerator()
  # Make one log on every process with the configuration for debugging.
  logging.basicConfig(
      format="""%(asctime)s - %(levelname)s - %(name)s - %(message)s"""  ,		datefmt="""%m/%d/%Y %H:%M:%S"""  ,		level=logging.INFO  ,		)
  logger.info(accelerator.state		)

  # Setup logging, we only want one process per machine to log things on the
  # screen. accelerator.is_local_main_process is only True for one process per
  # machine.
  logger.setLevel(logging.INFO if accelerator.is_local_main_process else logging.ERROR		)

  if accelerator.is_local_main_process:
    datasets.utils.logging.set_verbosity_warning()
    transformers.utils.logging.set_verbosity_info()
  else:
    datasets.utils.logging.set_verbosity_error()
    transformers.utils.logging.set_verbosity_error()

  __UpperCAmelCase							:	Union[str, Any]           =  STModelArguments(model_name_or_path=__lowerCamelCase		)
  __UpperCAmelCase							:	Optional[int]           =  STDataArguments(train_file=__lowerCamelCase  ,		infer_file=__lowerCamelCase		)
  __UpperCAmelCase							:	Optional[Any]           =  STTrainingArguments(output_dir=__lowerCamelCase		)
  __UpperCAmelCase							:	Optional[Any]           =  argparse.Namespace()

  for arg_class in (model_args, data_args, training_args):
    for key, value in vars(__lowerCamelCase		).items():
      setattr(__lowerCamelCase  ,		__lowerCamelCase  ,		__lowerCamelCase		)

  for key, value in kwargs.items():
    if hasattr(__lowerCamelCase  ,		__lowerCamelCase		):
      setattr(__lowerCamelCase  ,		__lowerCamelCase  ,		__lowerCamelCase		)

    # Sanity checks
  __UpperCAmelCase							:	List[Any]           =  {}
  __UpperCAmelCase							:	List[Any]           =  None

  # You need to provide the training data and the data to predict on
  assert args.train_file is not None
  assert args.infer_file is not None
  __UpperCAmelCase							:	Union[str, Any]           =  args.train_file
  __UpperCAmelCase							:	List[Any]           =  args.infer_file

  if args.evaluation_strategy != IntervalStrategy.NO.value:
    assert args.eval_file is not None
    __UpperCAmelCase							:	List[str]           =  args.eval_file

  for key in data_files:
    __UpperCAmelCase							:	Tuple           =  data_files[key].split("""."""		)[-1]
    assert extension in ["csv", "json"], f"""`{key}_file` should be a csv or a json file."""
    if args.data_file_extension is None:
      __UpperCAmelCase							:	Any           =  extension
    else:
      assert extension == args.data_file_extension, f"""`{key}_file` should be a {args.data_file_extension} file`."""

  assert (
      args.eval_metric in datasets.list_metrics()
  ), f"""{args.eval_metric} not in the list of supported metrics {datasets.list_metrics()}."""

  # If passed along, set the training seed now.
  if args.seed is not None:
    set_seed(args.seed		)

  logger.info("""Creating the initial data directory for self-training..."""		)
  __UpperCAmelCase							:	Dict           =  f"""{args.output_dir}/self-train_iter-{{}}""".format
  __UpperCAmelCase							:	Any           =  data_dir_format(0		)

  if accelerator.is_main_process:
    if args.output_dir is not None:
      os.makedirs(args.output_dir  ,		exist_ok=__lowerCamelCase		)
      os.makedirs(__lowerCamelCase  ,		exist_ok=__lowerCamelCase		)
  accelerator.wait_for_everyone()

  __UpperCAmelCase							:	Any           =  None
  __UpperCAmelCase							:	List[Any]           =  None
  __UpperCAmelCase							:	Any           =  0
  __UpperCAmelCase							:	Optional[int]           =  False
  # Show the progress bar
  __UpperCAmelCase							:	Dict           =  tqdm(range(args.max_selftrain_iterations		)  ,		disable=not accelerator.is_local_main_process		)

  # Self-train
  for iteration in range(0  ,		int(args.max_selftrain_iterations		)		):
    __UpperCAmelCase							:	Tuple           =  data_dir_format(__lowerCamelCase		)
    assert os.path.exists(__lowerCamelCase		)

    # Stage 1: initial fine-tuning for iteration = 0 or pseudo-training for
    # iteration > 0
    __UpperCAmelCase							:	Tuple           =  os.path.join(__lowerCamelCase  ,		"""stage-1"""		)
    __UpperCAmelCase							:	List[str]           =  {
        """accelerator""": accelerator,
        """model_name_or_path""": args.model_name_or_path,
        """cache_dir""": args.cache_dir,
        """do_train""": True,
        """train_file""": data_files["""train"""] if iteration == 0 else data_files["""train_pseudo"""],
        """do_eval""": True if args.eval_file is not None else False,
        """eval_file""": data_files["""eval"""],
        """do_predict""": True,
        """infer_file""": data_files["""infer"""],
        """task_name""": args.task_name,
        """label_list""": args.label_list,
        """output_dir""": current_output_dir,
        """eval_metric""": args.eval_metric,
        """evaluation_strategy""": args.evaluation_strategy,
        """early_stopping_patience""": args.early_stopping_patience,
        """early_stopping_threshold""": args.early_stopping_threshold,
        """seed""": args.seed,
    }
    # Add additional training arguments
    for key, value in kwargs.items():
      if key not in arguments_dict and not hasattr(__lowerCamelCase  ,		__lowerCamelCase		):
        arguments_dict.update({key: value}		)

    __UpperCAmelCase							:	Optional[Any]           =  os.path.join(__lowerCamelCase  ,		"""best-checkpoint"""  ,		__lowerCamelCase		)
    if os.path.exists(__lowerCamelCase		):
      logger.info(
          """Found existing model checkpoint at %s. Skipping self-training: iteration: %d, stage: 1."""  ,		__lowerCamelCase  ,		__lowerCamelCase  ,		)
    else:
      logger.info("""***** Running self-training: iteration: %d, stage: 1 *****"""  ,		__lowerCamelCase		)
      finetune(**__lowerCamelCase		)
      accelerator.wait_for_everyone()
      assert os.path.exists(__lowerCamelCase		)
      logger.info("""Self-training job completed: iteration: %d, stage: 1."""  ,		__lowerCamelCase		)

    if iteration > 0 and args.finetune_on_labeled_data:
      # Stage 2 (optional): fine-tuning on the original labeled data
      __UpperCAmelCase							:	int           =  os.path.join(__lowerCamelCase  ,		"""best-checkpoint"""		)
      __UpperCAmelCase							:	Optional[int]           =  os.path.join(__lowerCamelCase  ,		"""stage-2"""		)
      # Update arguments_dict
      __UpperCAmelCase							:	str           =  model_path
      __UpperCAmelCase							:	str           =  data_files["""train"""]
      __UpperCAmelCase							:	List[Any]           =  current_output_dir

      __UpperCAmelCase							:	Optional[Any]           =  os.path.join(__lowerCamelCase  ,		"""best-checkpoint"""  ,		__lowerCamelCase		)
      if os.path.exists(__lowerCamelCase		):
        logger.info(
            """Found existing model checkpoint at %s. Skipping self-training: iteration: %d, stage: 2."""  ,		__lowerCamelCase  ,		__lowerCamelCase  ,		)
      else:
        logger.info("""***** Running self-training: iteration: %d, stage: 2 *****"""  ,		__lowerCamelCase		)
        finetune(**__lowerCamelCase		)
        accelerator.wait_for_everyone()
        assert os.path.exists(__lowerCamelCase		)
        logger.info("""Self-training job completed: iteration: %d, stage: 2."""  ,		__lowerCamelCase		)

    __UpperCAmelCase							:	List[Any]           =  iteration
    __UpperCAmelCase							:	Tuple           =  data_dir_format(iteration + 1		)

    __UpperCAmelCase							:	Optional[int]           =  AutoConfig.from_pretrained(os.path.join(__lowerCamelCase  ,		"""best-checkpoint"""		)		)
    __UpperCAmelCase							:	Union[str, Any]           =  config.idalabel
    __UpperCAmelCase							:	Optional[Any]           =  os.path.join(__lowerCamelCase  ,		"""eval_results_best-checkpoint.json"""		)
    __UpperCAmelCase							:	int           =  os.path.join(__lowerCamelCase  ,		"""test_results_best-checkpoint.json"""		)
    assert os.path.exists(__lowerCamelCase		)

    with open(__lowerCamelCase  ,		"""r"""		) as f:
      __UpperCAmelCase							:	Tuple           =  float(json.load(__lowerCamelCase		)[args.eval_metric]		)
    __UpperCAmelCase							:	Dict           =  os.path.join(__lowerCamelCase  ,		"""infer_output_best-checkpoint.csv"""		)
    assert os.path.exists(__lowerCamelCase		)
    # Loading the dataset from local csv or json files.
    __UpperCAmelCase							:	Dict           =  load_dataset(args.data_file_extension  ,		data_files={"""data""": data_files["""infer"""]}		)["""data"""]
    __UpperCAmelCase							:	Tuple           =  load_dataset("""csv"""  ,		data_files={"""data""": infer_output_file}		)["""data"""]

    if accelerator.is_main_process:
      os.makedirs(__lowerCamelCase  ,		exist_ok=__lowerCamelCase		)
      shutil.copy(__lowerCamelCase  ,		os.path.join(__lowerCamelCase  ,		f"""eval_results_iter-{iteration}.json"""		)		)
      if os.path.exists(__lowerCamelCase		):
        shutil.copy(__lowerCamelCase  ,		os.path.join(__lowerCamelCase  ,		f"""test_results_iter-{iteration}.json"""		)		)
      create_pseudo_labeled_data(__lowerCamelCase  ,		__lowerCamelCase  ,		__lowerCamelCase  ,		__lowerCamelCase  ,		__lowerCamelCase  ,		__lowerCamelCase		)
    accelerator.wait_for_everyone()

    __UpperCAmelCase							:	int           =  os.path.join(__lowerCamelCase  ,		f"""train_pseudo.{args.data_file_extension}"""		)

    if args.evaluation_strategy != IntervalStrategy.NO.value:
      __UpperCAmelCase							:	List[Any]           =  eval_result

      if best_iteration is None:
        __UpperCAmelCase							:	List[Any]           =  new_iteration
        __UpperCAmelCase							:	Dict           =  new_eval_result
      else:
        if new_eval_result - best_eval_result > args.early_stopping_threshold:
          __UpperCAmelCase							:	Any           =  new_iteration
          __UpperCAmelCase							:	Optional[Any]           =  new_eval_result
          __UpperCAmelCase							:	List[str]           =  0
        else:
          if new_eval_result == best_eval_result:
            __UpperCAmelCase							:	Dict           =  new_iteration
            __UpperCAmelCase							:	Any           =  new_eval_result
          early_stopping_patience_counter += 1

        if early_stopping_patience_counter >= args.early_stopping_patience:
          __UpperCAmelCase							:	Union[str, Any]           =  True

    progress_bar.update(1		)

    if should_training_stop:
      break

  if best_iteration is not None:
    # Save the best iteration
    logger.info("""Best iteration: %d"""  ,		__lowerCamelCase		)
    logger.info("""Best evaluation result: %s = %f"""  ,		args.eval_metric  ,		__lowerCamelCase		)
    accelerator.wait_for_everyone()
    if accelerator.is_main_process:
      shutil.copy(
          os.path.join(__lowerCamelCase  ,		f"""eval_results_iter-{iteration}.json"""		)  ,		os.path.join(__lowerCamelCase  ,		"""eval_results_best-iteration.json"""		)  ,		)
  else:
    # Assume that the last iteration is the best
    logger.info("""Best iteration: %d"""  ,		args.max_selftrain_iterations - 1		)
    logger.info("""Best evaluation result: %s = %f"""  ,		args.eval_metric  ,		__lowerCamelCase		)
    accelerator.wait_for_everyone()
    if accelerator.is_main_process:
      shutil.copy(
          os.path.join(__lowerCamelCase  ,		f"""eval_results_iter-{args.max_selftrain_iterations - 1}.json"""		)  ,		os.path.join(__lowerCamelCase  ,		"""eval_results_best-iteration.json"""		)  ,		)










import warnings
from contextlib import contextmanager

from ....processing_utils import ProcessorMixin
class     a    ( lowercase__   ):



      """simple docstring"""


      a  : List[str]							       =	'MCTCTFeatureExtractor'
      a  : str							       =	'AutoTokenizer'
      def __init__(      self					:			Tuple		,      __lowercase					:			int		,      __lowercase					:			Dict					)							->      Any:
        super().__init__(__lowercase		,      __lowercase					)
        __UpperCAmelCase							:	Optional[Any]           =  self.feature_extractor
        __UpperCAmelCase							:	Optional[int]           =  False
      def __call__(      self					:			int		,      *__lowercase					:			Tuple		,      **__lowercase					:			Optional[int]					)							->      Union[str, Any]:
        # For backward compatibility
        if self._in_target_context_manager:
          return self.current_processor(*__lowercase		,      **__lowercase					)

        if "raw_speech" in kwargs:
          warnings.warn("""Using `raw_speech` as a keyword argument is deprecated. Use `audio` instead."""					)
          __UpperCAmelCase							:	Dict           =  kwargs.pop("""raw_speech"""					)
        else:
          __UpperCAmelCase							:	Dict           =  kwargs.pop("""audio"""		,      __lowercase					)
        __UpperCAmelCase							:	List[str]           =  kwargs.pop("""sampling_rate"""		,      __lowercase					)
        __UpperCAmelCase							:	Tuple           =  kwargs.pop("""text"""		,      __lowercase					)
        if len(__lowercase					) > 0:
          __UpperCAmelCase							:	Tuple           =  args[0]
          __UpperCAmelCase							:	str           =  args[1:]

        if audio is None and text is None:
          raise ValueError("""You need to specify either an `audio` or `text` input to process."""					)

        if audio is not None:
          __UpperCAmelCase							:	Tuple           =  self.feature_extractor(__lowercase		,      *__lowercase		,      sampling_rate=__lowercase		,      **__lowercase					)
        if text is not None:
          __UpperCAmelCase							:	str           =  self.tokenizer(__lowercase		,      **__lowercase					)

        if text is None:
          return inputs
        elif audio is None:
          return encodings
        else:
          __UpperCAmelCase							:	Dict           =  encodings["""input_ids"""]
          return inputs
      def 	UpperCAmelCase      (      self					:			Optional[Any]		,      *__lowercase					:			List[Any]		,      **__lowercase					:			int					)							->      List[Any]:
        return self.tokenizer.batch_decode(*__lowercase		,      **__lowercase					)
      def 	UpperCAmelCase      (      self					:			Optional[int]		,      *__lowercase					:			Optional[Any]		,      **__lowercase					:			List[str]					)							->      int:
        # For backward compatibility
        if self._in_target_context_manager:
          return self.current_processor.pad(*__lowercase		,      **__lowercase					)

        __UpperCAmelCase							:	Optional[int]           =  kwargs.pop("""input_features"""		,      __lowercase					)
        __UpperCAmelCase							:	Optional[Any]           =  kwargs.pop("""labels"""		,      __lowercase					)
        if len(__lowercase					) > 0:
          __UpperCAmelCase							:	Union[str, Any]           =  args[0]
          __UpperCAmelCase							:	str           =  args[1:]

        if input_features is not None:
          __UpperCAmelCase							:	Any           =  self.feature_extractor.pad(__lowercase		,      *__lowercase		,      **__lowercase					)
        if labels is not None:
          __UpperCAmelCase							:	Union[str, Any]           =  self.tokenizer.pad(__lowercase		,      **__lowercase					)

        if labels is None:
          return input_features
        elif input_features is None:
          return labels
        else:
          __UpperCAmelCase							:	Any           =  labels["""input_ids"""]
          return input_features
      def 	UpperCAmelCase      (      self					:			Any		,      *__lowercase					:			Union[str, Any]		,      **__lowercase					:			Dict					)							->      List[Any]:
        return self.tokenizer.decode(*__lowercase		,      **__lowercase					)




      @contextmanager
      def 	UpperCAmelCase      (      self					:			Optional[Any]					)							->      Tuple:
        warnings.warn(
            """`as_target_processor` is deprecated and will be removed in v5 of Transformers. You can process your """
            """labels by using the argument `text` of the regular `__call__` method (either in the same call as """
            """your audio inputs, or in a separate call."""					)
        __UpperCAmelCase							:	Any           =  True
        __UpperCAmelCase							:	Optional[int]           =  self.tokenizer
        yield
        __UpperCAmelCase							:	List[Any]           =  self.feature_extractor
        __UpperCAmelCase							:	int           =  False


