



"""simple docstring"""







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
UpperCamelCase     =							False
UpperCamelCase     =							False

def       _lowerCamelCase				(							UpperCAmelCase_ :       Namespace     )	-> str:






	"""simple docstring"""





	return TrainCommand(UpperCAmelCase_     )






class       UpperCamelCase__			(   _lowerCAmelCase      ):

			"""simple docstring"""


			@staticmethod
			def   snake_case__	(      SCREAMING_SNAKE_CASE__		)      ->	Tuple:
				A__											=					parser.add_parser("train"						,	help="CLI tool to train a model on a task."		)

				train_parser.add_argument(
				    "--train_data"						,	type=SCREAMING_SNAKE_CASE__						,	required=SCREAMING_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=SCREAMING_SNAKE_CASE__						,	default=0						,	help="Column of the dataset csv file with example labels."		)
				train_parser.add_argument(
				    "--column_text"						,	type=SCREAMING_SNAKE_CASE__						,	default=1						,	help="Column of the dataset csv file with example texts."		)
				train_parser.add_argument(
				    "--column_id"						,	type=SCREAMING_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=SCREAMING_SNAKE_CASE__						,	default=""						,	help="path to validation dataset."		)
				train_parser.add_argument(
				    "--validation_split"						,	type=SCREAMING_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=SCREAMING_SNAKE_CASE__						,	default="./"						,	help="path to saved the trained model."		)

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


			def __init__(      self						,	SCREAMING_SNAKE_CASE__		)      ->	Dict:
				A__											=					logging.get_logger("transformers-cli/training"		)

				A__											=					"tf" if is_tf_available() else "torch"

				os.makedirs(args.output						,	exist_ok=SCREAMING_SNAKE_CASE__		)
				A__											=					args.output

				A__											=					args.column_label
				A__											=					args.column_text
				A__											=					args.column_id

				self.logger.info(f"""Loading {args.task} pipeline for {args.model}"""		)
				if args.task == "text_classification":
					A__											=					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}"""		)
				A__											=					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						,	)
				A__											=					None
				if args.validation_data:
					self.logger.info(f"""Loading validation dataset from {args.validation_data}"""		)
					A__											=					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						,	)

				A__											=					args.validation_split
				A__											=					args.train_batch_size
				A__											=					args.valid_batch_size
				A__											=					args.learning_rate
				A__											=					args.adam_epsilon


			def   snake_case__	(      self		)      ->	Union[str, Any]:
				if self.framework == "tf":
					return self.run_tf()
				return self.run_torch()


			def   snake_case__	(      self		)      ->	List[Any]:
				raise NotImplementedError







			def   snake_case__	(      self		)      ->	Dict:
				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		)









"""simple docstring"""







def       _lowerCamelCase				(							UpperCAmelCase_ :       bytes     )	-> str:






	"""simple docstring"""





	return "".join([hex(UpperCAmelCase_     )[2:].zfill(2     ).upper() for byte in list(UpperCAmelCase_     )]     )

def       _lowerCamelCase				(							UpperCAmelCase_ :       str     )	-> bytes:






	"""simple docstring"""





	if (len(UpperCAmelCase_     ) % 2) != 0:
		raise ValueError(
		    "Base16 encoded data is invalid:\nData does not have an even number of hex digits."     )
	# Check the character set - the standard base16 alphabet
	# is uppercase according to RFC3548 section 6
	if not set(UpperCAmelCase_     ) <= set("0123456789ABCDEF"     ):
		raise ValueError(
		    "Base16 encoded data is invalid:\nData is not uppercase hex or it contains invalid characters."     )
	# For every two hexadecimal digits (= a byte), turn it into an integer.
	# Then, string the result together into bytes, and return it.
	return bytes(int(data[i] + data[i + 1],	16     ) for i in range(0,	len(UpperCAmelCase_     ),	2     )     )


if __name__ == "__main__":
			import doctest

			doctest.testmod()




