





"""simple docstring"""





import sacrebleu as scb
from packaging import version

import datasets


SCREAMING_SNAKE_CASE__ =       "\\n@inproceedings{post-2018-call,\n    title = \"A Call for Clarity in Reporting {BLEU} Scores\",\n    author = \"Post, Matt\",\n    booktitle = \"Proceedings of the Third Conference on Machine Translation: Research Papers\",\n    month = oct,\n    year = \"2018\",\n    address = \"Belgium, Brussels\",\n    publisher = \"Association for Computational Linguistics\",\n    url = \"https://www.aclweb.org/anthology/W18-6319\",\n    pages = \"186--191\",\n}\n"

SCREAMING_SNAKE_CASE__ =       "\\nSacreBLEU provides hassle-free computation of shareable, comparable, and reproducible BLEU scores.\nInspired by Rico Sennrich's `multi-bleu-detok.perl`, it produces the official WMT scores but works with plain text.\nIt also knows all the standard test sets and handles downloading, processing, and tokenization for you.\n\nSee the [README.md] file at https://github.com/mjpost/sacreBLEU for more information.\n"

SCREAMING_SNAKE_CASE__ =       "\nProduces BLEU scores along with its sufficient statistics\nfrom a source against one or more references.\n\nArgs:\n    predictions (`list` of `str`): list of translations to score. Each translation should be tokenized into a list of tokens.\n    references (`list` of `list` of `str`): A list of lists of references. The contents of the first sub-list are the references for the first prediction, the contents of the second sub-list are for the second prediction, etc. Note that there must be the same number of references for each prediction (i.e. all sub-lists must be of the same length).\n    smooth_method (`str`): The smoothing method to use, defaults to `'exp'`. Possible values are:\n        - `'none'`: no smoothing\n        - `'floor'`: increment zero counts\n        - `'add-k'`: increment num/denom by k for n>1\n        - `'exp'`: exponential decay\n    smooth_value (`float`): The smoothing value. Only valid when `smooth_method='floor'` (in which case `smooth_value` defaults to `0.1`) or `smooth_method='add-k'` (in which case `smooth_value` defaults to `1`).\n    tokenize (`str`): Tokenization method to use for BLEU. If not provided, defaults to `'zh'` for Chinese, `'ja-mecab'` for Japanese and `'13a'` (mteval) otherwise. Possible values are:\n        - `'none'`: No tokenization.\n        - `'zh'`: Chinese tokenization.\n        - `'13a'`: mimics the `mteval-v13a` script from Moses.\n        - `'intl'`: International tokenization, mimics the `mteval-v14` script from Moses\n        - `'char'`: Language-agnostic character-level tokenization.\n        - `'ja-mecab'`: Japanese tokenization. Uses the [MeCab tokenizer](https://pypi.org/project/mecab-python3).\n    lowercase (`bool`): If `True`, lowercases the input, enabling case-insensitivity. Defaults to `False`.\n    force (`bool`): If `True`, insists that your tokenized input is actually detokenized. Defaults to `False`.\n    use_effective_order (`bool`): If `True`, stops including n-gram orders for which precision is 0. This should be `True`, if sentence-level BLEU will be computed. Defaults to `False`.\n\nReturns:\n    'score': BLEU score,\n    'counts': Counts,\n    'totals': Totals,\n    'precisions': Precisions,\n    'bp': Brevity penalty,\n    'sys_len': predictions length,\n    'ref_len': reference length,\n\nExamples:\n\n    Example 1:\n        >>> predictions = [\"hello there general kenobi\", \"foo bar foobar\"]\n        >>> references = [[\"hello there general kenobi\", \"hello there !\"], [\"foo bar foobar\", \"foo bar foobar\"]]\n        >>> sacrebleu = datasets.load_metric(\"sacrebleu\")\n        >>> results = sacrebleu.compute(predictions=predictions, references=references)\n        >>> print(list(results.keys()))\n        ['score', 'counts', 'totals', 'precisions', 'bp', 'sys_len', 'ref_len']\n        >>> print(round(results[\"score\"], 1))\n        100.0\n\n    Example 2:\n        >>> predictions = [\"hello there general kenobi\",\n        ...                 \"on our way to ankh morpork\"]\n        >>> references = [[\"hello there general kenobi\", \"hello there !\"],\n        ...                 [\"goodbye ankh morpork\", \"ankh morpork\"]]\n        >>> sacrebleu = datasets.load_metric(\"sacrebleu\")\n        >>> results = sacrebleu.compute(predictions=predictions,\n        ...                             references=references)\n        >>> print(list(results.keys()))\n        ['score', 'counts', 'totals', 'precisions', 'bp', 'sys_len', 'ref_len']\n        >>> print(round(results[\"score\"], 1))\n        39.8\n"

@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION					,  _KWARGS_DESCRIPTION )
class 		lowercase ( datasets.Metric ):





      def    _snake_case      (	self			)		->					List[str]:
            if version.parse(scb.__version__			) < version.parse("""1.4.12"""			):
                  raise ImportWarning(
                      """To use `sacrebleu`, the module `sacrebleu>=1.4.12` is required, and the current version of `sacrebleu` doesn't match this condition.\n"""
                      """You can install it with `pip install \"sacrebleu>=1.4.12\"`."""			)
            return datasets.MetricInfo(
                description=_DESCRIPTION				,						citation=_CITATION				,						homepage="""https://github.com/mjpost/sacreBLEU"""				,						inputs_description=_KWARGS_DESCRIPTION				,						features=datasets.Features(
                    {
                        """predictions""": datasets.Value("""string"""				,						id="""sequence"""			),
                        """references""": datasets.Sequence(datasets.Value("""string"""				,						id="""sequence"""			)				,						id="""references"""			),
                    }			)				,						codebase_urls=["""https://github.com/mjpost/sacreBLEU"""]				,						reference_urls=[
                    """https://github.com/mjpost/sacreBLEU""",
                    """https://en.wikipedia.org/wiki/BLEU""",
                    """https://towardsdatascience.com/evaluating-text-output-in-nlp-bleu-at-your-own-risk-e8609665a213""",
                ]				,						)





      def    _snake_case      (	self				,						lowercase				,						lowercase				,						lowercase="exp"				,						lowercase=None				,						lowercase=False				,						lowercase=False				,						lowercase=None				,						lowercase=False				,						)		->					int:
            lowerCAmelCase  						=	len(references[0]			)
            if any(len(lowercase			) != references_per_prediction for refs in references			):
                  raise ValueError("""Sacrebleu requires the same number of references for each prediction"""			)
            lowerCAmelCase  						=	[[refs[i] for refs in references] for i in range(lowercase			)]
            lowerCAmelCase  						=	scb.corpus_bleu(
                lowercase				,						lowercase				,						smooth_method=lowercase				,						smooth_value=lowercase				,						force=lowercase				,						lowercase=lowercase				,						use_effective_order=lowercase				,						**({"""tokenize""": tokenize} if tokenize else {})				,						)
            lowerCAmelCase  						=	{
                """score""": output.score,
                """counts""": output.counts,
                """totals""": output.totals,
                """precisions""": output.precisions,
                """bp""": output.bp,
                """sys_len""": output.sys_len,
                """ref_len""": output.ref_len,
            }
            return output_dict













"""simple docstring"""





from __future__ import annotations

import unittest
import warnings

from transformers import AutoTokenizer, MarianConfig, MarianTokenizer, TranslationPipeline, is_tf_available
from transformers.testing_utils import require_sentencepiece, require_tf, require_tokenizers, slow
from transformers.utils import cached_property

from ...test_configuration_common import ConfigTester
from ...test_modeling_tf_common import TFModelTesterMixin, ids_tensor
from ...test_pipeline_mixin import PipelineTesterMixin


if is_tf_available():
       import tensorflow as tf

       from transformers import TFAutoModelForSeqaSeqLM, TFMarianModel, TFMarianMTModel

@require_tf
class 		lowercase :
      _SCREAMING_SNAKE_CASE         =				MarianConfig
      _SCREAMING_SNAKE_CASE         =				{}
      _SCREAMING_SNAKE_CASE         =				'gelu'





      def __init__(	self				,						lowercase				,						lowercase=13				,						lowercase=7				,						lowercase=True				,						lowercase=False				,						lowercase=99				,						lowercase=32				,						lowercase=2				,						lowercase=4				,						lowercase=37				,						lowercase=0.1				,						lowercase=0.1				,						lowercase=20				,						lowercase=2				,						lowercase=1				,						lowercase=0				,						)		->					int:
            lowerCAmelCase  						=	parent
            lowerCAmelCase  						=	batch_size
            lowerCAmelCase  						=	seq_length
            lowerCAmelCase  						=	is_training
            lowerCAmelCase  						=	use_labels
            lowerCAmelCase  						=	vocab_size
            lowerCAmelCase  						=	hidden_size
            lowerCAmelCase  						=	num_hidden_layers
            lowerCAmelCase  						=	num_attention_heads
            lowerCAmelCase  						=	intermediate_size

            lowerCAmelCase  						=	hidden_dropout_prob
            lowerCAmelCase  						=	attention_probs_dropout_prob
            lowerCAmelCase  						=	max_position_embeddings
            lowerCAmelCase  						=	eos_token_id
            lowerCAmelCase  						=	pad_token_id
            lowerCAmelCase  						=	bos_token_id





      def    _snake_case      (	self			)		->					List[str]:
            lowerCAmelCase  						=	ids_tensor([self.batch_size, self.seq_length - 1]				,						self.vocab_size			)
            lowerCAmelCase  						=	tf.expand_dims(tf.constant([self.eos_token_id] * self.batch_size			)				,						1			)
            lowerCAmelCase  						=	tf.concat([input_ids, eos_tensor]				,						axis=1			)

            lowerCAmelCase  						=	ids_tensor([self.batch_size, self.seq_length]				,						self.vocab_size			)

            lowerCAmelCase  						=	self.config_cls(
                vocab_size=self.vocab_size				,						d_model=self.hidden_size				,						encoder_layers=self.num_hidden_layers				,						decoder_layers=self.num_hidden_layers				,						encoder_attention_heads=self.num_attention_heads				,						decoder_attention_heads=self.num_attention_heads				,						encoder_ffn_dim=self.intermediate_size				,						decoder_ffn_dim=self.intermediate_size				,						dropout=self.hidden_dropout_prob				,						attention_dropout=self.attention_probs_dropout_prob				,						max_position_embeddings=self.max_position_embeddings				,						eos_token_ids=[2]				,						bos_token_id=self.bos_token_id				,						pad_token_id=self.pad_token_id				,						decoder_start_token_id=self.pad_token_id				,						**self.config_updates				,						)
            lowerCAmelCase  						=	prepare_marian_inputs_dict(lowercase				,						lowercase				,						lowercase			)
            return config, inputs_dict





      def    _snake_case      (	self				,						lowercase				,						lowercase			)		->					Union[str, Any]:
            lowerCAmelCase  						=	TFMarianModel(config=lowercase			).get_decoder()
            lowerCAmelCase  						=	inputs_dict["""input_ids"""]

            lowerCAmelCase  						=	input_ids[:1, :]
            lowerCAmelCase  						=	inputs_dict["""attention_mask"""][:1, :]
            lowerCAmelCase  						=	inputs_dict["""head_mask"""]
            lowerCAmelCase  						=	1

            # first forward pass
            lowerCAmelCase  						=	model(lowercase				,						attention_mask=lowercase				,						head_mask=lowercase				,						use_cache=lowercase			)

            lowerCAmelCase						,		lowerCAmelCase  						=	outputs.to_tuple()

            # create hypothetical next token and extent to next_input_ids
            lowerCAmelCase  						=	ids_tensor((self.batch_size, 3)				,						config.vocab_size			)
            lowerCAmelCase  						=	tf.cast(ids_tensor((self.batch_size, 3)				,						2			)				,						tf.inta			)

            # append to next input_ids and
            lowerCAmelCase  						=	tf.concat([input_ids, next_tokens]				,						axis=-1			)
            lowerCAmelCase  						=	tf.concat([attention_mask, next_attn_mask]				,						axis=-1			)

            lowerCAmelCase  						=	model(lowercase				,						attention_mask=lowercase			)[0]
            lowerCAmelCase  						=	model(lowercase				,						attention_mask=lowercase				,						past_key_values=lowercase			)[0]

            self.parent.assertEqual(next_tokens.shape[1]				,						output_from_past.shape[1]			)

            # select random slice
            lowerCAmelCase  						=	int(ids_tensor((1,)				,						output_from_past.shape[-1]			)			)
            lowerCAmelCase  						=	output_from_no_past[:, -3:, random_slice_idx]
            lowerCAmelCase  						=	output_from_past[:, :, random_slice_idx]

            # test that outputs are equal for slice
            tf.debugging.assert_near(lowercase				,						lowercase				,						rtol=1e-3			)







def       UpperCAmelCase__							(  SCREAMING_SNAKE_CASE					:						int							,						SCREAMING_SNAKE_CASE					:						List[str]							,						SCREAMING_SNAKE_CASE					:						Union[str, Any]							,						SCREAMING_SNAKE_CASE					:						Any=None							,						SCREAMING_SNAKE_CASE					:						str=None							,						SCREAMING_SNAKE_CASE					:						List[str]=None							,						SCREAMING_SNAKE_CASE					:						Tuple=None							,						SCREAMING_SNAKE_CASE					:						Dict=None							,						):







      '''simple docstring'''




      if attention_mask is None:
            lowerCAmelCase  						=	tf.cast(tf.math.not_equal(SCREAMING_SNAKE_CASE							,						config.pad_token_id      )							,						tf.inta      )
      if decoder_attention_mask is None:
            lowerCAmelCase  						=	tf.concat(
                [
                    tf.ones(decoder_input_ids[:, :1].shape							,						dtype=tf.inta      ),
                    tf.cast(tf.math.not_equal(decoder_input_ids[:, 1:]							,						config.pad_token_id      )							,						tf.inta      ),
                ]							,						axis=-1							,						)
      if head_mask is None:
            lowerCAmelCase  						=	tf.ones((config.encoder_layers, config.encoder_attention_heads)      )
      if decoder_head_mask is None:
            lowerCAmelCase  						=	tf.ones((config.decoder_layers, config.decoder_attention_heads)      )
      if cross_attn_head_mask is None:
            lowerCAmelCase  						=	tf.ones((config.decoder_layers, config.decoder_attention_heads)      )
      return {
          "input_ids": input_ids,
          "decoder_input_ids": decoder_input_ids,
          "attention_mask": attention_mask,
          "decoder_attention_mask": decoder_attention_mask,
          "head_mask": head_mask,
          "decoder_head_mask": decoder_head_mask,
          "cross_attn_head_mask": cross_attn_head_mask,
      }

@require_tf
class 		lowercase ( _UpperCAmelCase					,  _UpperCAmelCase					,  unittest.TestCase ):
      _SCREAMING_SNAKE_CASE         =				(TFMarianMTModel, TFMarianModel) if is_tf_available() else ()
      _SCREAMING_SNAKE_CASE         =				(TFMarianMTModel,) if is_tf_available() else ()
      _SCREAMING_SNAKE_CASE         =				(
          {
              'conversational': TFMarianMTModel,
              'feature-extraction': TFMarianModel,
              'summarization': TFMarianMTModel,
              'text2text-generation': TFMarianMTModel,
              'translation': TFMarianMTModel,
          }
          if is_tf_available()
          else {}
      )
      _SCREAMING_SNAKE_CASE         =				True
      _SCREAMING_SNAKE_CASE         =				False
      _SCREAMING_SNAKE_CASE         =				False





      def    _snake_case      (	self			)		->					Optional[int]:
            lowerCAmelCase  						=	TFMarianModelTester(self			)
            lowerCAmelCase  						=	ConfigTester(self				,						config_class=lowercase			)





      def    _snake_case      (	self			)		->					str:
            self.config_tester.run_common_tests()





      def    _snake_case      (	self			)		->					str:
            lowerCAmelCase  						=	self.model_tester.prepare_config_and_inputs_for_common()
            self.model_tester.check_decoder_model_past_large_inputs(*lowercase			)







@require_tf
class 		lowercase ( unittest.TestCase ):
      _SCREAMING_SNAKE_CASE         =				1_000  # show more chars for failing integration tests





      @classmethod
      def    _snake_case      (	cls			)		->					None:
            lowerCAmelCase  						=	f'Helsinki-NLP/opus-mt-{cls.src}-{cls.tgt}'
            return cls





      @cached_property
      def    _snake_case      (	self			)		->					MarianTokenizer:
            return AutoTokenizer.from_pretrained(self.model_name			)





      @property
      def    _snake_case      (	self			)		->					int:
            return self.tokenizer.eos_token_id





      @cached_property
      def    _snake_case      (	self			)		->					Any:
            warnings.simplefilter("""error"""			)
            lowerCAmelCase  						=	TFAutoModelForSeqaSeqLM.from_pretrained(self.model_name			)
            assert isinstance(lowercase				,						lowercase			)
            lowerCAmelCase  						=	model.config
            self.assertListEqual(c.bad_words_ids				,						[[c.pad_token_id]]			)
            self.assertEqual(c.max_length				,						512			)
            self.assertEqual(c.decoder_start_token_id				,						c.pad_token_id			)
            return model





      def    _snake_case      (	self				,						**lowercase			)		->					Tuple:
            lowerCAmelCase  						=	self.translate_src_text(**lowercase			)
            self.assertListEqual(self.expected_text				,						lowercase			)





      def    _snake_case      (	self				,						**lowercase			)		->					Union[str, Any]:
            lowerCAmelCase  						=	self.tokenizer(self.src_text				,						**lowercase				,						padding=lowercase				,						return_tensors="""tf"""			)
            lowerCAmelCase  						=	self.model.generate(
                model_inputs.input_ids				,						attention_mask=model_inputs.attention_mask				,						num_beams=2				,						max_length=128			)
            lowerCAmelCase  						=	self.tokenizer.batch_decode(generated_ids.numpy()				,						skip_special_tokens=lowercase			)
            return generated_words







@require_sentencepiece
@require_tokenizers
@require_tf
class 		lowercase ( _UpperCAmelCase ):
      _SCREAMING_SNAKE_CASE         =				'mt'
      _SCREAMING_SNAKE_CASE         =				'en'
      _SCREAMING_SNAKE_CASE         =				['Billi messu b\'mod ġentili, Ġesù fejjaq raġel li kien milqut bil - marda kerha tal - ġdiem.']
      _SCREAMING_SNAKE_CASE         =				['Touching gently, Jesus healed a man who was affected by the sad disease of leprosy.']





      @unittest.skip("""Skipping until #12647 is resolved."""			)
      @slow
      def    _snake_case      (	self			)		->					List[Any]:
            self._assert_generated_batch_equal_expected()







@require_sentencepiece
@require_tokenizers
@require_tf
class 		lowercase ( _UpperCAmelCase ):
      _SCREAMING_SNAKE_CASE         =				'en'
      _SCREAMING_SNAKE_CASE         =				'zh'
      _SCREAMING_SNAKE_CASE         =				['My name is Wolfgang and I live in Berlin']
      _SCREAMING_SNAKE_CASE         =				['我叫沃尔夫冈 我住在柏林']





      @unittest.skip("""Skipping until #12647 is resolved."""			)
      @slow
      def    _snake_case      (	self			)		->					Dict:
            self._assert_generated_batch_equal_expected()







@require_sentencepiece
@require_tokenizers
@require_tf
class 		lowercase ( _UpperCAmelCase ):
      _SCREAMING_SNAKE_CASE         =				'en'
      _SCREAMING_SNAKE_CASE         =				'ROMANCE'
      _SCREAMING_SNAKE_CASE         =				[
          '>>fr<< Don\'t spend so much time watching TV.',
          '>>pt<< Your message has been sent.',
          '>>es<< He\'s two years older than me.',
      ]
      _SCREAMING_SNAKE_CASE         =				[
          'Ne passez pas autant de temps à regarder la télé.',
          'A sua mensagem foi enviada.',
          'Es dos años más viejo que yo.',
      ]





      @unittest.skip("""Skipping until #12647 is resolved."""			)
      @slow
      def    _snake_case      (	self			)		->					List[str]:
            self._assert_generated_batch_equal_expected()





      @unittest.skip("""Skipping until #12647 is resolved."""			)
      @slow
      def    _snake_case      (	self			)		->					List[str]:
            lowerCAmelCase  						=	TranslationPipeline(self.model				,						self.tokenizer				,						framework="""tf"""			)
            lowerCAmelCase  						=	pipeline(self.src_text			)
            self.assertEqual(self.expected_text				,						[x["""translation_text"""] for x in output]			)






