

"""simple docstring"""

import jax
import jax.numpy as jnp
from bigbird_flax import FlaxBigBirdForNaturalQuestions
from datasets import load_from_disk

from transformers import BigBirdTokenizerFast


a__ :	Any						= {0: """null""", 1: """short""", 2: """long""", 3: """yes""", 4: """no"""}
a__ :	List[str]						= set("""""".join(["""‘""", """’""", """´""", """`""", """.""", """,""", """-""", """\""""]))





def 				__UpperCamelCase   (    a__: Union[str, Any] ,	a__: Optional[int]=0 ,	a__: List[Any]=None			)				->			Union[str, Any]:




					"""simple docstring"""



					return [" ".join(x.split(''' '''			)[begin:end]			) for x in answers if len(x.split(''' '''			)			) > 1]





def 				__UpperCamelCase   (    a__: Optional[Any] ,	a__: List[str]=False			)				->			str:




					"""simple docstring"""



					if make_sub_answers:
										# if answers are longer than one word, make sure a predictions is correct if it coresponds to the complete 1: or :-1 sub word
										# *e.g.* if the correct answer contains a prefix such as "the", or "a"
										__lowercase												=			(
										    given_answers + get_sub_answers(a__ ,	begin=1			) + get_sub_answers(a__ ,	end=-1			)
										)
					__lowercase												=			[]
					for answer in given_answers:
										__lowercase												=			answer.replace('''_''' ,	''' '''			).lower()
										__lowercase												=			''''''.join(c if c not in PUNCTUATION_SET_TO_EXCLUDE else ''' ''' for c in alias			)
										answers.append(''' '''.join(alias.split()			).strip()			)
					return set(a__			)





def 				__UpperCamelCase   (    a__: List[Any] ,	a__: int ,	a__: Any=1 ,	a__: Union[str, Any]=1_00			)				->			Optional[int]:




					"""simple docstring"""



					__lowercase						, __lowercase												=			jax.lax.top_k(a__ ,	a__			)
					__lowercase						, __lowercase												=			jax.lax.top_k(a__ ,	a__			)

					__lowercase												=			best_end_idx[:, None] - best_start_idx[None, :]
					__lowercase												=			jnp.logical_or(widths < 0 ,	widths > max_size			)
					__lowercase												=			(best_end_scores[:, None] + best_start_scores[None, :]) - (1e8 * mask)
					__lowercase												=			jnp.argmax(a__			).item()

					return best_start_idx[best_score % top_k], best_end_idx[best_score // top_k]





def 				__UpperCamelCase   (    a__: Any			)				->			Optional[int]:




					"""simple docstring"""



					__lowercase												=			sample['''question''']['''text''']
					__lowercase												=			sample['''document''']['''tokens''']['''token''']
					__lowercase												=			sample['''document''']['''tokens''']['''is_html''']
					__lowercase												=			sample['''annotations''']['''long_answer''']
					__lowercase												=			sample['''annotations''']['''short_answers''']

					__lowercase												=			''' '''.join([context[i] for i in range(len(a__			)			) if not is_html[i]]			)

					# 0 - No ; 1 - Yes
					for answer in sample["annotations"]["yes_no_answer"]:
										if answer == 0 or answer == 1:
															return {
															    "question": question,
															    "context": context_string,
															    "short": [],
															    "long": [],
															    "category": "no" if answer == 0 else "yes",
															}

					__lowercase												=			[]
					for s in short_answers:
										short_targets.extend(s['''text''']			)
					__lowercase												=			list(set(a__			)			)

					__lowercase												=			[]
					for s in long_answers:
										if s["start_token"] == -1:
															continue
										__lowercase												=			context[s['''start_token'''] : s['''end_token''']]
										__lowercase												=			is_html[s['''start_token'''] : s['''end_token''']]
										__lowercase												=			''' '''.join([answer[i] for i in range(len(a__			)			) if not html[i]]			)
										if new_answer not in long_targets:
															long_targets.append(a__			)

					__lowercase												=			'''long_short''' if len(short_targets + long_targets			) > 0 else '''null'''

					return {
					    "question": question,
					    "context": context_string,
					    "short": short_targets,
					    "long": long_targets,
					    "category": category,
					}





def 				__UpperCamelCase   (    )				->			List[Any]:




					"""simple docstring"""



					__lowercase												=			load_from_disk('''natural-questions-validation'''			)
					__lowercase												=			dataset.map(a__			).remove_columns(['''annotations''', '''document''', '''id''']			)
					print(a__			)

					__lowercase												=			dataset.filter(lambda a__			: (len(x['''question''']			) + len(x['''context''']			)) < 4 * 40_96			)
					__lowercase												=			short_validation_dataset.filter(lambda a__			: x["category"] != "null"			)
					short_validation_dataset

					__lowercase												=			'''vasudevgupta/flax-bigbird-natural-questions'''
					__lowercase												=			FlaxBigBirdForNaturalQuestions.from_pretrained(a__			)
					__lowercase												=			BigBirdTokenizerFast.from_pretrained(a__			)

					@jax.jit
					def forward(*a__: Tuple ,	**a__: List[Any]			):
										__lowercase						, __lowercase						, __lowercase												=			model(*a__ ,	**a__			)
										return start_logits, end_logits, jnp.argmax(a__ ,	axis=-1			)

					def evaluate(a__: Optional[Any]			):
										# encode question and context so that they are separated by a tokenizer.sep_token and cut at max_length
										__lowercase												=			tokenizer(
										    example['''question'''] ,	example['''context'''] ,	return_tensors='''np''' ,	max_length=40_96 ,	padding='''max_length''' ,	truncation=a__ ,	)

										__lowercase						, __lowercase						, __lowercase												=			forward(**a__			)

										__lowercase												=			CATEGORY_MAPPING[category.item()]

										__lowercase												=			example['''long'''] + example['''short''']
										if example["category"] in ["yes", "no", "null"]:
															__lowercase												=			[example['''category''']]
										__lowercase												=			example['''category'''] != '''null'''
										# Now target can be: "yes", "no", "null", "list of long & short answers"

										if predicted_category in ["yes", "no", "null"]:
															__lowercase												=			[predicted_category]
															__lowercase												=			example['''output'''] == example['''targets''']
															__lowercase												=			predicted_category != '''null'''
															return example

										__lowercase												=			38 if predicted_category == '''short''' else 10_24
										__lowercase						, __lowercase												=			get_best_valid_start_end_idx(
										    start_scores[0] ,	end_scores[0] ,	top_k=8 ,	max_size=a__			)

										__lowercase												=			inputs['''input_ids'''][0].tolist()
										__lowercase												=			[tokenizer.decode(input_ids[start_score : end_score + 1]			)]

										__lowercase												=			expand_to_aliases(example['''targets'''] ,	make_sub_answers=a__			)
										__lowercase												=			expand_to_aliases(example['''output''']			)

										# some preprocessing to both prediction and answer
										__lowercase												=			{''''''.join(a.split()			) for a in answers}
										__lowercase												=			{''''''.join(p.split()			) for p in predictions}
										__lowercase												=			{s for s in predictions if s not in ['''``''', '''\'\'''', '''`''', '''\'''']}

										# if there is a common element, it's a exact match
										__lowercase												=			len(list(answers & predictions			)			) > 0
										__lowercase												=			predicted_category != '''null''' and len(a__			) > 0

										return example

					__lowercase												=			short_validation_dataset.map(a__			)

					__lowercase												=			len(a__			)
					__lowercase												=			len(short_validation_dataset.filter(lambda a__			: x["match"] == 1			)			)
					print('''EM score:''' ,	(matched / total) * 1_00 ,	'''%'''			)


if __name__ == "__main__":
							main()





"""simple docstring"""

import logging
import os
import sys
from dataclasses import dataclass, field
from typing import Optional

import transformers
from transformers import (
    AutoConfig,
    AutoModelForQuestionAnswering,
    AutoTokenizer,
    DataCollatorWithPadding,
    HfArgumentParser,
    SquadDataset,
    Trainer,
    TrainingArguments,
)
from transformers import SquadDataTrainingArguments as DataTrainingArguments
from transformers.trainer_utils import is_main_process


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


@dataclass
class 			_snake_case     :
						__snake_case 			=     field(
						    metadata={'help': 'Path to pretrained model or model identifier from huggingface.co/models'}       )
						__snake_case 			=     field(
						    default=UpperCamelCase						,			metadata={'help': 'Pretrained config name or path if not the same as model_name'}       )
						__snake_case 			=     field(
						    default=UpperCamelCase						,			metadata={'help': 'Pretrained tokenizer name or path if not the same as model_name'}       )
						__snake_case 			=     field(default=UpperCamelCase						,			metadata={'help': 'Set this flag to use fast tokenization.'}       )
						# If you want to tweak more attributes on your tokenizer, you should do it in a distinct script,
						# or just modify its tokenizer_config.json.
						__snake_case 			=     field(
						    default=UpperCamelCase						,			metadata={'help': 'Where do you want to store the pretrained models downloaded from huggingface.co'}						,			)





def 				__UpperCamelCase   (    )				->			Union[str, Any]:




					"""simple docstring"""



					__lowercase												=			HfArgumentParser((ModelArguments, DataTrainingArguments, TrainingArguments)			)

					if len(sys.argv			) == 2 and sys.argv[1].endswith('''.json'''			):
										# If we pass only one argument to the script and it's the path to a json file,
										# let's parse it to get our arguments.
										__lowercase						, __lowercase						, __lowercase												=			parser.parse_json_file(json_file=os.path.abspath(sys.argv[1]			)			)
					else:
										__lowercase						, __lowercase						, __lowercase												=			parser.parse_args_into_dataclasses()

					if (
					    os.path.exists(training_args.output_dir			)
					    and os.listdir(training_args.output_dir			)
					    and training_args.do_train
					    and not training_args.overwrite_output_dir
					):
										raise ValueError(
										    f'''Output directory ({training_args.output_dir}) already exists and is not empty. Use'''
										    ''' --overwrite_output_dir to overcome.'''			)

					# Setup logging
					logging.basicConfig(
					    format='''%(asctime)s - %(levelname)s - %(name)s - %(message)s''' ,	datefmt='''%m/%d/%Y %H:%M:%S''' ,	level=logging.INFO if training_args.local_rank in [-1, 0] else logging.WARN ,	)
					logger.warning(
					    '''Process rank: %s, device: %s, n_gpu: %s, distributed training: %s, 16-bits training: %s''' ,	training_args.local_rank ,	training_args.device ,	training_args.n_gpu ,	bool(training_args.local_rank != -1			) ,	training_args.fpaa ,	)
					# Set the verbosity to info of the Transformers logger (on main process only):
					if is_main_process(training_args.local_rank			):
										transformers.utils.logging.set_verbosity_info()
										transformers.utils.logging.enable_default_handler()
										transformers.utils.logging.enable_explicit_format()
					logger.info('''Training/evaluation parameters %s''' ,	a__			)

					# Prepare Question-Answering task
					# Load pretrained model and tokenizer
					#
					# Distributed training:
					# The .from_pretrained methods guarantee that only one local process can concurrently
					# download model & vocab.

					__lowercase												=			AutoConfig.from_pretrained(
					    model_args.config_name if model_args.config_name else model_args.model_name_or_path ,	cache_dir=model_args.cache_dir ,	)
					__lowercase												=			AutoTokenizer.from_pretrained(
					    model_args.tokenizer_name if model_args.tokenizer_name else model_args.model_name_or_path ,	cache_dir=model_args.cache_dir ,	use_fast=a__ ,	)
					__lowercase												=			AutoModelForQuestionAnswering.from_pretrained(
					    model_args.model_name_or_path ,	from_tf=bool('''.ckpt''' in model_args.model_name_or_path			) ,	config=a__ ,	cache_dir=model_args.cache_dir ,	)

					# Get datasets
					__lowercase												=			hasattr(model.config ,	'''lang2id'''			)
					__lowercase												=			(
					    SquadDataset(
					        a__ ,	tokenizer=a__ ,	is_language_sensitive=a__ ,	cache_dir=model_args.cache_dir			)
					    if training_args.do_train
					    else None
					)
					__lowercase												=			(
					    SquadDataset(
					        a__ ,	tokenizer=a__ ,	mode='''dev''' ,	is_language_sensitive=a__ ,	cache_dir=model_args.cache_dir ,	)
					    if training_args.do_eval
					    else None
					)

					# Data collator
					__lowercase												=			DataCollatorWithPadding(a__ ,	pad_to_multiple_of=8			) if training_args.fpaa else None

					# Initialize our Trainer
					__lowercase												=			Trainer(
					    model=a__ ,	args=a__ ,	train_dataset=a__ ,	eval_dataset=a__ ,	data_collator=a__ ,	)

					# Training
					if training_args.do_train:
										trainer.train(
										    model_path=model_args.model_name_or_path if os.path.isdir(model_args.model_name_or_path			) else None			)
										trainer.save_model()
										# For convenience, we also re-save the tokenizer to the same directory,
										# so that you can share your model easily on huggingface.co/models =)
										if trainer.is_world_master():
															tokenizer.save_pretrained(training_args.output_dir			)





def 				__UpperCamelCase   (    a__: Any			)				->			Any:




					"""simple docstring"""



					main()


if __name__ == "__main__":
							main()


