



'''simple docstring'''






import json
import os
import subprocess
import unittest
from ast import literal_eval

import pytest
from parameterized import parameterized, parameterized_class

from . import is_sagemaker_available


if is_sagemaker_available():
						from sagemaker import Session, TrainingJobAnalytics
						from sagemaker.huggingface import HuggingFace

@pytest.mark.skipif(
    literal_eval(os.getenv("""TEST_SAGEMAKER"""							,	"""False"""    )    ) is not True							,	reason="""Skipping test because should only be run when releasing minor transformers version"""							,	)
@pytest.mark.usefixtures("""sm_env"""    )
@parameterized_class(
    [
        {
            """framework""": """pytorch""",
            """script""": """run_glue.py""",
            """model_name_or_path""": """distilbert-base-cased""",
            """instance_type""": """ml.p3.16xlarge""",
            """results""": {"""train_runtime""": 650, """eval_accuracy""": 0.7, """eval_loss""": 0.6},
        },
        {
            """framework""": """pytorch""",
            """script""": """run_ddp.py""",
            """model_name_or_path""": """distilbert-base-cased""",
            """instance_type""": """ml.p3.16xlarge""",
            """results""": {"""train_runtime""": 600, """eval_accuracy""": 0.7, """eval_loss""": 0.6},
        },
        {
            """framework""": """tensorflow""",
            """script""": """run_tf_dist.py""",
            """model_name_or_path""": """distilbert-base-cased""",
            """instance_type""": """ml.p3.16xlarge""",
            """results""": {"""train_runtime""": 600, """eval_accuracy""": 0.6, """eval_loss""": 0.7},
        },
    ]    )
class        SCREAMING_SNAKE_CASE(							unittest.TestCase    ):







	"""simple docstring"""






	def   A			(		self    :  List[str]	)    ->	int:
								if self.framework == "pytorch":
															subprocess.run(
															    F"""cp ./examples/pytorch/text-classification/run_glue.py {self.env.test_path}/run_glue.py""".split()	,    encoding='''utf-8'''	,    check=__snake_case	,    )
								assert hasattr(self	,    '''env'''	)







	def   A			(		self    :  int	,    __snake_case    :  Dict	)    ->	str:
								UpperCAmelCase				: List[Any]											=	F"""{self.env.base_job_name}-{instance_count}-{"ddp" if "ddp" in self.script else "smd"}"""
								# distributed data settings
								UpperCAmelCase				: Optional[int]											=	{'''smdistributed''': {'''dataparallel''': {'''enabled''': True}}} if self.script != '''run_ddp.py''' else None

								# creates estimator
								return HuggingFace(
								    entry_point=self.script	,    source_dir=self.env.test_path	,    role=self.env.role	,    image_uri=self.env.image_uri	,    base_job_name=__snake_case	,    instance_count=__snake_case	,    instance_type=self.instance_type	,    debugger_hook_config=__snake_case	,    hyperparameters={**self.env.distributed_hyperparameters, '''model_name_or_path''': self.model_name_or_path}	,    metric_definitions=self.env.metric_definitions	,    distribution=__snake_case	,    py_version='''py36'''	,    )







	def   A			(		self    :  List[Any]	,    __snake_case    :  Optional[Any]	)    ->	Optional[int]:
								TrainingJobAnalytics(__snake_case	).export_csv(F"""{self.env.test_path}/{job_name}_metrics.csv"""	)







	@parameterized.expand([(2,)]	)
	def   A			(		self    :  Optional[int]	,    __snake_case    :  int	)    ->	int:
								# create estimator
								UpperCAmelCase				: Tuple											=	self.create_estimator(__snake_case	)

								# run training
								estimator.fit()

								# result dataframe
								UpperCAmelCase				: Optional[int]											=	TrainingJobAnalytics(estimator.latest_training_job.name	).dataframe()

								# extract kpis
								UpperCAmelCase				: List[str]											=	list(result_metrics_df[result_metrics_df.metric_name == '''eval_accuracy''']['''value''']	)
								UpperCAmelCase				: Union[str, Any]											=	list(result_metrics_df[result_metrics_df.metric_name == '''eval_loss''']['''value''']	)
								# get train time from SageMaker job, this includes starting, preprocessing, stopping
								UpperCAmelCase				: Tuple											=	(
								    Session().describe_training_job(estimator.latest_training_job.name	).get('''TrainingTimeInSeconds'''	,    999999	)
								)

								# assert kpis
								assert train_runtime <= self.results["train_runtime"]
								assert all(t >= self.results['''eval_accuracy'''] for t in eval_accuracy	)
								assert all(t <= self.results['''eval_loss'''] for t in eval_loss	)

								# dump tests result into json file to share in PR
								with open(F"""{estimator.latest_training_job.name}.json"""	,    '''w'''	) as outfile:
															json.dump({'''train_time''': train_runtime, '''eval_accuracy''': eval_accuracy, '''eval_loss''': eval_loss}	,    __snake_case	)










'''simple docstring'''






import argparse
import logging
import os

import datasets
import tensorflow as tf

from transformers import AutoTokenizer


UpperCamelCase__:     List[Any]										=    logging.getLogger(__name__)


def 				snake_case_  (      )   ->     int:
							UpperCAmelCase				: int											=	argparse.ArgumentParser(
							    description='''Prepare TFRecord shards from pre-tokenized samples of the wikitext dataset.'''						)
							parser.add_argument(
							    '''--dataset_name'''     ,   type=_lowerCAmelCase     ,   default='''wikitext'''     ,   help='''Name of the training. Explore datasets at: hf.co/datasets.'''     ,   )
							parser.add_argument(
							    '''--dataset_config'''     ,   type=_lowerCAmelCase     ,   default='''wikitext-103-raw-v1'''     ,   help='''Configuration name of the dataset.'''						)
							parser.add_argument(
							    '''--tokenizer_name_or_path'''     ,   type=_lowerCAmelCase     ,   default='''sayakpaul/unigram-tokenizer-wikitext'''     ,   help='''Tokenizer identifier. Can be a local filepath or a Hub identifier.'''     ,   )
							parser.add_argument(
							    '''--shard_size'''     ,   type=_lowerCAmelCase     ,   default=1000     ,   help='''Number of entries to go in a single shard.'''     ,   )
							parser.add_argument('''--split'''     ,   type=_lowerCAmelCase     ,   default='''train'''     ,   choices=['''train''', '''test''', '''validation''']						)
							parser.add_argument(
							    '''--limit'''     ,   default=_lowerCAmelCase     ,   type=_lowerCAmelCase     ,   help='''Limit the number of shards (used for debugging).'''     ,   )
							parser.add_argument(
							    '''--max_length'''     ,   type=_lowerCAmelCase     ,   default=512     ,   help='''Maximum sequence length. For training on TPUs, it helps to have a maximum'''
							    ''' sequence length that is a multiple of 8.'''     ,   )
							parser.add_argument(
							    '''--output_dir'''     ,   default='''tf-tpu'''     ,   type=_lowerCAmelCase     ,   help='''Output directory where the TFRecord shards will be saved. If the'''
							    ''' path is appended with `gs://` (\'gs://tf-tpu\', for example) then the TFRecord'''
							    ''' shards will be directly saved to a Google Cloud Storage bucket.'''     ,   )

							UpperCAmelCase				: List[str]											=	parser.parse_args()
							return args


def 				snake_case_  (      _lowerCAmelCase						:		Union[str, Any]						)   ->     Optional[int]:
							def fn(_lowerCAmelCase						:		Tuple						):
														return tokenizer(examples['''text''']						)

							return fn


def 				snake_case_  (      _lowerCAmelCase						:		int						)   ->     Dict:
							UpperCAmelCase				: Optional[Any]											=	[]
							for i in range(len(tokenized_data['''input_ids''']						)						):
														UpperCAmelCase				: Optional[Any]											=	{
														    '''input_ids''': tf.train.Feature(intaa_list=tf.train.IntaaList(value=tokenized_data['''input_ids'''][i]						)						),
														    '''attention_mask''': tf.train.Feature(
														        intaa_list=tf.train.IntaaList(value=tokenized_data['''attention_mask'''][i]						)						),
														}
														UpperCAmelCase				: Optional[Any]											=	tf.train.Features(feature=_lowerCAmelCase						)
														UpperCAmelCase				: Union[str, Any]											=	tf.train.Example(features=_lowerCAmelCase						)
														UpperCAmelCase				: Any											=	example.SerializeToString()
														records.append(_lowerCAmelCase						)
							return records


def 				snake_case_  (      _lowerCAmelCase						:		List[str]						)   ->     List[str]:
							UpperCAmelCase				: List[str]											=	datasets.load_dataset(args.dataset_name     ,   args.dataset_config     ,   split=args.split						)

							if args.limit is not None:
														UpperCAmelCase				: List[Any]											=	min(len(_lowerCAmelCase						)     ,   args.limit						)
														UpperCAmelCase				: Dict											=	dataset.select(range(_lowerCAmelCase						)						)
														print(f"""Limiting the dataset to {args.limit} entries."""						)

							UpperCAmelCase				: List[Any]											=	AutoTokenizer.from_pretrained(args.tokenizer_name_or_path						)

							# Handle output directory creation.
							# For serializing into a Google Cloud Storage Bucket, one needs to first
							# create a bucket.
							if "gs" not in args.output_dir:
														if not os.path.exists(args.output_dir						):
																					os.makedirs(args.output_dir						)
														UpperCAmelCase				: List[Any]											=	os.path.join(args.output_dir     ,   args.split						)
														if not os.path.exists(_lowerCAmelCase						):
																					os.makedirs(_lowerCAmelCase						)
							else:
														UpperCAmelCase				: Tuple											=	os.path.join(args.output_dir     ,   args.split						)

							# Tokenize the whole dataset at once.
							UpperCAmelCase				: Optional[Any]											=	tokenize_function(_lowerCAmelCase						)
							UpperCAmelCase				: int											=	dataset.map(_lowerCAmelCase     ,   batched=_lowerCAmelCase     ,   num_proc=4     ,   remove_columns=['''text''']						)

							# We need to concatenate all our texts together, and then split the result
							# into chunks of a fixed size, which we will call block_size. To do this, we
							# will use the map method again, with the option batched=True. When we use batched=True,
							# the function we pass to map() will be passed multiple inputs at once, allowing us
							# to group them into more or fewer examples than we had in the input.
							# This allows us to create our new fixed-length samples. The advantage of this
							# method is that we don't lose a whole lot of content from the dataset compared to the
							# case where we simply tokenize with a pre-defined max_length.

							def group_texts(_lowerCAmelCase						:		List[str]						):
														# Concatenate all texts.
														UpperCAmelCase				: Optional[Any]											=	{k: sum(examples[k]     ,   []						) for k in examples.keys()}
														UpperCAmelCase				: Optional[Any]											=	len(concatenated_examples[list(examples.keys()						)[0]]						)
														# We drop the small remainder, though you could add padding instead if the model supports it
														# In this, as in all things, we advise you to follow your heart 🫀
														UpperCAmelCase				: Any											=	(total_length // args.max_length) * args.max_length
														# Split by chunks of max_len.
														UpperCAmelCase				: List[str]											=	{
														    k: [t[i : i + args.max_length] for i in range(0     ,   _lowerCAmelCase     ,   args.max_length						)]
														    for k, t in concatenated_examples.items()
														}
														return result

							UpperCAmelCase				: str											=	dataset_tokenized.map(_lowerCAmelCase     ,   batched=_lowerCAmelCase     ,   batch_size=1000     ,   num_proc=4						)

							UpperCAmelCase				: Union[str, Any]											=	0
							UpperCAmelCase				: Dict											=	0
							for shard in range(0     ,   len(_lowerCAmelCase						)     ,   args.shard_size						):
														UpperCAmelCase				: Union[str, Any]											=	grouped_dataset[shard : shard + args.shard_size]
														UpperCAmelCase				: Optional[int]											=	len(dataset_snapshot['''input_ids''']						)
														UpperCAmelCase				: Dict											=	os.path.join(_lowerCAmelCase     ,   f"""dataset-{shard_count}-{records_containing}.tfrecord"""						)
														UpperCAmelCase				: List[Any]											=	get_serialized_examples(_lowerCAmelCase						)

														with tf.io.TFRecordWriter(_lowerCAmelCase						) as out_file:
																					for i in range(len(_lowerCAmelCase						)						):
																												UpperCAmelCase				: Any											=	serialized_examples[i]
																												out_file.write(_lowerCAmelCase						)
																					print('''Wrote file {} containing {} records'''.format(_lowerCAmelCase     ,   _lowerCAmelCase						)						)

														shard_count += 1
														total_records += records_containing

							with open(f"""split-{args.split}-records-count.txt"""     ,   '''w'''						) as f:
														print(f"""Total {args.split} records: {total_records}"""     ,   file=_lowerCAmelCase						)


if __name__ == "__main__":
						UpperCamelCase__:     List[Any]										=    parse_args()
						main(args)





