






"""simple docstring"""




import enum
import warnings

from ..tokenization_utils import TruncationStrategy
from ..utils import add_end_docstrings, is_tf_available, is_torch_available, logging
from .base import PIPELINE_INIT_ARGS, Pipeline


if is_tf_available():
 import tensorflow as tf

 from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING

if is_torch_available():
 from ..models.auto.modeling_auto import MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING

_snake_case        =  logging.get_logger(__name__)






class 			UpperCamelCase     (      enum.Enum ):
 UpperCamelCase   :			Union[str, Any]     =   0
 UpperCamelCase   :			List[Any]     =   1







@add_end_docstrings(A_ )
class 			UpperCamelCase     (      A_ ):
 UpperCamelCase   :			Union[str, Any]     =   "generated"


 def __init__(	self						:		Union[str, Any]				,		*UpperCAmelCase__						:		Tuple				,		**UpperCAmelCase__						:		Optional[int]				)   ->			List[Any]:
   super().__init__(*snake_case__				,		**snake_case__				)

   self.check_model_type(
       TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING
       if self.framework == """tf"""
       else MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING				)


 def _lowercase      (	self						:		Any				,		UpperCAmelCase__						:		Optional[int]=None				,		UpperCAmelCase__						:		List[str]=None				,		UpperCAmelCase__						:		List[str]=None				,		UpperCAmelCase__						:		Union[str, Any]=None				,		UpperCAmelCase__						:		str=None				,		UpperCAmelCase__						:		List[Any]=None				,		**UpperCAmelCase__						:		Tuple				,		)   ->			Any:
   _a    :			Union[str, Any]			 =      {}
   if truncation is not None:
     _a    :			Dict			 =      truncation

   _a    :			List[str]			 =      generate_kwargs

   _a    :			str			 =      {}
   if return_tensors is not None and return_type is None:
     _a    :			Optional[Any]			 =      ReturnType.TENSORS if return_tensors else ReturnType.TEXT
   if return_type is not None:
     _a    :			Dict			 =      return_type

   if clean_up_tokenization_spaces is not None:
     _a    :			Tuple			 =      clean_up_tokenization_spaces

   if stop_sequence is not None:
     _a    :			Union[str, Any]			 =      self.tokenizer.encode(snake_case__				,		add_special_tokens=snake_case__				)
     if len(snake_case__				) > 1:
       warnings.warn(
           """Stopping on a multiple token sequence is not yet supported on transformers. The first token of"""
           """ the stop sequence will be used as the stop sequence string in the interim."""				)
     _a    :			List[str]			 =      stop_sequence_ids[0]

   return preprocess_params, forward_params, postprocess_params


 def _lowercase      (	self						:		Dict				,		UpperCAmelCase__						:		int				,		UpperCAmelCase__						:		int				,		UpperCAmelCase__						:		int				)   ->			str:
   return True


 def _lowercase      (	self						:		Dict				,		*UpperCAmelCase__						:		Union[str, Any]				,		UpperCAmelCase__						:		List[str]				)   ->			List[str]:
   _a    :			List[str]			 =      self.model.config.prefix if self.model.config.prefix is not None else ""
   if isinstance(args[0]				,		snake_case__				):
     if self.tokenizer.pad_token_id is None:
       raise ValueError("""Please make sure that the tokenizer has a pad_token_id when using a batch input"""				)
     _a    :			Union[str, Any]			 =      ([prefix + arg for arg in args[0]],)
     _a    :			str			 =      True

   elif isinstance(args[0]				,		snake_case__				):
     _a    :			Tuple			 =      (prefix + args[0],)
     _a    :			Optional[Any]			 =      False
   else:
     raise ValueError(
         f""" `args[0]`: {args[0]} have the wrong format. The should be either of type `str` or type `list`"""				)
   _a    :			List[str]			 =      self.tokenizer(*snake_case__				,		padding=snake_case__				,		truncation=snake_case__				,		return_tensors=self.framework				)
   # This is produced by tokenizers but is an invalid generate kwargs
   if "token_type_ids" in inputs:
     del inputs["token_type_ids"]
   return inputs


 def __call__(	self						:		Union[str, Any]				,		*UpperCAmelCase__						:		Optional[Any]				,		**UpperCAmelCase__						:		int				)   ->			int:
   _a    :			int			 =      super().__call__(*snake_case__				,		**snake_case__				)
   if (
       isinstance(args[0]				,		snake_case__				)
       and all(isinstance(snake_case__				,		snake_case__				) for el in args[0]				)
       and all(len(snake_case__				) == 1 for res in result				)
   ):
     return [res[0] for res in result]
   return result


 def _lowercase      (	self						:		List[Any]				,		UpperCAmelCase__						:		Dict				,		UpperCAmelCase__						:		Any=TruncationStrategy.DO_NOT_TRUNCATE				,		**UpperCAmelCase__						:		List[Any]				)   ->			Any:
   _a    :			str			 =      self._parse_and_tokenize(snake_case__				,		truncation=snake_case__				,		**snake_case__				)
   return inputs


 def _lowercase      (	self						:		Optional[Any]				,		UpperCAmelCase__						:		Union[str, Any]				,		**UpperCAmelCase__						:		List[str]				)   ->			int:


   if self.framework == "pt":
     _a    :			Union[str, Any]			 =      model_inputs["input_ids"].shape
   elif self.framework == "tf":
     _a    :			str			 =      tf.shape(model_inputs["""input_ids"""]				).numpy()

   _a    :			Optional[Any]			 =      generate_kwargs.get("""min_length"""				,		self.model.config.min_length				)
   _a    :			Optional[int]			 =      generate_kwargs.get("""max_length"""				,		self.model.config.max_length				)
   self.check_inputs(snake_case__				,		generate_kwargs["""min_length"""]				,		generate_kwargs["""max_length"""]				)
   _a    :			Tuple			 =      self.model.generate(**snake_case__				,		**snake_case__				)
   _a    :			str			 =      output_ids.shape[0]
   if self.framework == "pt":
     _a    :			int			 =      output_ids.reshape(snake_case__				,		out_b // in_b				,		*output_ids.shape[1:]				)
   elif self.framework == "tf":
     _a    :			Any			 =      tf.reshape(snake_case__				,		(in_b, out_b // in_b, *output_ids.shape[1:])				)
   return {"output_ids": output_ids}







 def _lowercase      (	self						:		List[str]				,		UpperCAmelCase__						:		int				,		UpperCAmelCase__						:		str=ReturnType.TEXT				,		UpperCAmelCase__						:		Union[str, Any]=False				)   ->			Dict:
   _a    :			Optional[Any]			 =      []
   for output_ids in model_outputs["output_ids"][0]:
     if return_type == ReturnType.TENSORS:
       _a    :			Dict			 =      {f"""{self.return_name}_token_ids""": output_ids}
     elif return_type == ReturnType.TEXT:
       _a    :			Optional[Any]			 =      {
           f"""{self.return_name}_text""": self.tokenizer.decode(
               snake_case__				,		skip_special_tokens=snake_case__				,		clean_up_tokenization_spaces=snake_case__				,		)
       }
     records.append(snake_case__				)
   return records







@add_end_docstrings(A_ )
class 			UpperCamelCase     (      A_ ):
 UpperCamelCase   :			Union[str, Any]     =   "summary"


 def __call__(	self						:		str				,		*UpperCAmelCase__						:		Any				,		**UpperCAmelCase__						:		Any				)   ->			Optional[int]:
   return super().__call__(*snake_case__				,		**snake_case__				)







 def _lowercase      (	self						:		Any				,		UpperCAmelCase__						:		int				,		UpperCAmelCase__						:		int				,		UpperCAmelCase__						:		int				)   ->			bool:


   if max_length < min_length:
     logger.warning(f"""Your min_length={min_length} must be inferior than your max_length={max_length}."""				)

   if input_length < max_length:
     logger.warning(
         f"""Your max_length is set to {max_length}, but your input_length is only {input_length}. Since this is """
         """a summarization task, where outputs shorter than the input are typically wanted, you might """
         f"""consider decreasing max_length manually, e.g. summarizer('...', max_length={input_length//2})"""				)







@add_end_docstrings(A_ )
class 			UpperCamelCase     (      A_ ):
 UpperCamelCase   :			int     =   "translation"


 def _lowercase      (	self						:		Any				,		UpperCAmelCase__						:		int				,		UpperCAmelCase__						:		int				,		UpperCAmelCase__						:		int				)   ->			str:


   if input_length > 0.9 * max_length:
     logger.warning(
         f"""Your input_length: {input_length} is bigger than 0.9 * max_length: {max_length}. You might consider """
         """increasing your max_length manually, e.g. translator('...', max_length=400)"""				)
   return True


 def _lowercase      (	self						:		int				,		*UpperCAmelCase__						:		List[str]				,		UpperCAmelCase__						:		Union[str, Any]=TruncationStrategy.DO_NOT_TRUNCATE				,		UpperCAmelCase__						:		str=None				,		UpperCAmelCase__						:		Dict=None				)   ->			Optional[Any]:


   if getattr(self.tokenizer				,		"""_build_translation_inputs"""				,		snake_case__				):
     return self.tokenizer._build_translation_inputs(
         *snake_case__				,		return_tensors=self.framework				,		truncation=snake_case__				,		src_lang=snake_case__				,		tgt_lang=snake_case__				)
   else:
     return super()._parse_and_tokenize(*snake_case__				,		truncation=snake_case__				)


 def _lowercase      (	self						:		List[Any]				,		UpperCAmelCase__						:		Tuple=None				,		UpperCAmelCase__						:		str=None				,		**UpperCAmelCase__						:		Union[str, Any]				)   ->			List[str]:
   _a    :			List[str]			 =      super()._sanitize_parameters(**snake_case__				)
   if src_lang is not None:
     _a    :			List[Any]			 =      src_lang
   if tgt_lang is not None:
     _a    :			int			 =      tgt_lang
   if src_lang is None and tgt_lang is None:
     # Backward compatibility, direct arguments use is preferred.
     _a    :			Any			 =      kwargs.get("""task"""				,		self.task				)
     _a    :			Optional[Any]			 =      task.split("""_"""				)
     if task and len(snake_case__				) == 4:
       # translation, XX, to YY
       _a    :			List[str]			 =      items[1]
       _a    :			Any			 =      items[3]
   return preprocess_params, forward_params, postprocess_params







 def __call__(	self						:		Dict				,		*UpperCAmelCase__						:		List[str]				,		**UpperCAmelCase__						:		int				)   ->			str:
   return super().__call__(*snake_case__				,		**snake_case__				)



import os
from argparse import ArgumentParser, Namespace

from ..data import SingleSentenceClassificationProcessor as Processor
from ..pipelines import TextClassificationPipeline
from ..utils import is_tf_available, is_torch_available, logging
from . import BaseTransformersCLICommand


if not is_tf_available() and not is_torch_available():
   raise RuntimeError("""At least one of PyTorch or TensorFlow 2.0+ should be installed to use CLI training""")

# TF training parameters
__lowerCamelCase				=			False
__lowerCamelCase				=			False


def      UpperCamelCase   (       __lowerCamelCase	:					Namespace       ):
       return TrainCommand(__lowerCamelCase       )






class     UpperCAmelCase						(		A_					):



   @staticmethod
   def 							_SCREAMING_SNAKE_CASE  (snake_case__						:   ArgumentParser					)						->      int:


          '''simple docstring'''


          snake_case			:  Any     							= parser.add_parser("train"       ,		help="CLI tool to train a model on a task."					)

          train_parser.add_argument(
              "--train_data"       ,		type=snake_case__       ,		required=snake_case__       ,		help="path to train (and optionally evaluation) dataset as a csv with tab separated labels and sentences."       ,		)
          train_parser.add_argument(
              "--column_label"       ,		type=snake_case__       ,		default=0       ,		help="Column of the dataset csv file with example labels."					)
          train_parser.add_argument(
              "--column_text"       ,		type=snake_case__       ,		default=1       ,		help="Column of the dataset csv file with example texts."					)
          train_parser.add_argument(
              "--column_id"       ,		type=snake_case__       ,		default=2       ,		help="Column of the dataset csv file with example ids."					)
          train_parser.add_argument(
              "--skip_first_row"       ,		action="store_true"       ,		help="Skip the first row of the csv file (headers)."					)

          train_parser.add_argument("--validation_data"       ,		type=snake_case__       ,		default=""       ,		help="path to validation dataset."					)
          train_parser.add_argument(
              "--validation_split"       ,		type=snake_case__       ,		default=0.1       ,		help="if validation dataset is not provided, fraction of train dataset to use as validation dataset."       ,		)

          train_parser.add_argument("--output"       ,		type=snake_case__       ,		default="./"       ,		help="path to saved the trained model."					)

          train_parser.add_argument(
              "--task"       ,		type=snake_case__       ,		default="text_classification"       ,		help="Task to train the model on."					)
          train_parser.add_argument(
              "--model"       ,		type=snake_case__       ,		default="bert-base-uncased"       ,		help="Model's name or path to stored model."					)
          train_parser.add_argument("--train_batch_size"       ,		type=snake_case__       ,		default=32       ,		help="Batch size for training."					)
          train_parser.add_argument("--valid_batch_size"       ,		type=snake_case__       ,		default=64       ,		help="Batch size for validation."					)
          train_parser.add_argument("--learning_rate"       ,		type=snake_case__       ,		default=3e-5       ,		help="Learning rate."					)
          train_parser.add_argument("--adam_epsilon"       ,		type=snake_case__       ,		default=1e-08       ,		help="Epsilon for Adam optimizer."					)
          train_parser.set_defaults(func=snake_case__					)



   def __init__(self						:   List[Any]       ,		snake_case__						:   Namespace					)						->      Tuple:


          '''simple docstring'''


          snake_case			:  Any     							= logging.get_logger("transformers-cli/training"					)

          snake_case			:  List[Any]     							= "tf" if is_tf_available() else "torch"

          os.makedirs(args.output       ,		exist_ok=snake_case__					)
          snake_case			:  Any     							= args.output

          snake_case			:  List[Any]     							= args.column_label
          snake_case			:  Tuple     							= args.column_text
          snake_case			:  str     							= args.column_id

          self.logger.info(f"""Loading {args.task} pipeline for {args.model}"""					)
          if args.task == "text_classification":
                 snake_case			:  Optional[int]     							= TextClassificationPipeline.from_pretrained(args.model					)
          elif args.task == "token_classification":
                 raise NotImplementedError
          elif args.task == "question_answering":
                 raise NotImplementedError

          self.logger.info(f"""Loading dataset from {args.train_data}"""					)
          snake_case			:  Tuple     							= Processor.create_from_csv(
              args.train_data       ,		column_label=args.column_label       ,		column_text=args.column_text       ,		column_id=args.column_id       ,		skip_first_row=args.skip_first_row       ,		)
          snake_case			:  Optional[Any]     							= None
          if args.validation_data:
                 self.logger.info(f"""Loading validation dataset from {args.validation_data}"""					)
                 snake_case			:  Dict     							= Processor.create_from_csv(
                     args.validation_data       ,		column_label=args.column_label       ,		column_text=args.column_text       ,		column_id=args.column_id       ,		skip_first_row=args.skip_first_row       ,		)

          snake_case			:  Union[str, Any]     							= args.validation_split
          snake_case			:  Optional[Any]     							= args.train_batch_size
          snake_case			:  List[str]     							= args.valid_batch_size
          snake_case			:  List[Any]     							= args.learning_rate
          snake_case			:  List[Any]     							= args.adam_epsilon



   def 							_SCREAMING_SNAKE_CASE  (self						:   int					)						->      List[str]:


          '''simple docstring'''


          if self.framework == "tf":
                 return self.run_tf()
          return self.run_torch()



   def 							_SCREAMING_SNAKE_CASE  (self						:   Tuple					)						->      Optional[Any]:


          '''simple docstring'''


          raise NotImplementedError



   def 							_SCREAMING_SNAKE_CASE  (self						:   Optional[Any]					)						->      Tuple:


          '''simple docstring'''


          self.pipeline.fit(
              self.train_dataset       ,		validation_data=self.valid_dataset       ,		validation_split=self.validation_split       ,		learning_rate=self.learning_rate       ,		adam_epsilon=self.adam_epsilon       ,		train_batch_size=self.train_batch_size       ,		valid_batch_size=self.valid_batch_size       ,		)

          # Save trained pipeline
          self.pipeline.save_pretrained(self.output					)





