




import argparse
import os

# New Code #
import evaluate
import torch
from datasets import load_dataset
from torch.optim import AdamW
from torch.utils.data import DataLoader
from transformers import AutoModelForSequenceClassification, AutoTokenizer, get_linear_schedule_with_warmup, set_seed

from accelerate import Accelerator, DistributedType
from accelerate.utils import find_executable_batch_size


########################################################################
# This is a fully working simple example to use Accelerate,
# specifically showcasing how to ensure out-of-memory errors never
# interrupt training, and builds off the `nlp_example.py` script.
#
# This example trains a Bert base model on GLUE MRPC
# in any of the following settings (with the same script):
#   - single CPU or single GPU
#   - multi GPUS (using PyTorch distributed mode)
#   - (multi) TPUs
#   - fp16 (mixed-precision) or fp32 (normal precision)
#
# New additions from the base script can be found quickly by
# looking for the # New Code # tags
#
# To run it in each of these various modes, follow the instructions
# in the readme for examples:
# https://github.com/huggingface/accelerate/tree/main/examples
#
########################################################################


_snake_case										=       16
_snake_case										=       32







def 				lowerCAmelCase_	(     snake_case_,snake_case_ = 16     ):
      _A							:     List[str]			=						AutoTokenizer.from_pretrained("""bert-base-cased"""     )
      _A							:     int			=						load_dataset("""glue""","""mrpc"""     )

      def tokenize_function(snake_case_     ):
            # max_length=None => use the model max length (it's actually the default)
            _A							:     Optional[Any]			=						tokenizer(examples["""sentence1"""],examples["""sentence2"""],truncation=_UpperCAmelCase,max_length=_UpperCAmelCase     )
            return outputs

      # Apply the method we just defined to all the examples in all the splits of the dataset
      # starting with the main process first:
      with accelerator.main_process_first():
            _A							:     List[str]			=						datasets.map(
                _UpperCAmelCase,batched=_UpperCAmelCase,remove_columns=["""idx""", """sentence1""", """sentence2"""],)

      # We also rename the 'label' column to 'labels' which is the expected name for labels by the models of the
      # transformers library
      _A							:     Tuple			=						tokenized_datasets.rename_column("""label""","""labels"""     )

      def collate_fn(snake_case_     ):
            # On TPU it's best to pad everything to the same length or training will be very slow.
            _A							:     Union[str, Any]			=						128 if accelerator.distributed_type == DistributedType.TPU else None
            # When using mixed precision we want round multiples of 8/16
            if accelerator.mixed_precision == "fp8":
                  _A							:     Dict			=						16
            elif accelerator.mixed_precision != "no":
                  _A							:     List[Any]			=						8
            else:
                  _A							:     Optional[int]			=						None

            return tokenizer.pad(
                _UpperCAmelCase,padding="""longest""",max_length=_UpperCAmelCase,pad_to_multiple_of=_UpperCAmelCase,return_tensors="""pt""",)

      # Instantiate dataloaders.
      _A							:     Tuple			=						DataLoader(
          tokenized_datasets["""train"""],shuffle=_UpperCAmelCase,collate_fn=_UpperCAmelCase,batch_size=_UpperCAmelCase     )
      _A							:     Any			=						DataLoader(
          tokenized_datasets["""validation"""],shuffle=_UpperCAmelCase,collate_fn=_UpperCAmelCase,batch_size=_UpperCAmelCase     )

      return train_dataloader, eval_dataloader


# For testing only
if os.environ.get("TESTING_MOCKED_DATALOADERS", None) == "1":
  from accelerate.test_utils.training import mocked_dataloaders

  _snake_case										=       mocked_dataloaders  # noqa: F811







def 				lowerCAmelCase_	(     snake_case_,snake_case_     ):
      # For testing only
      if os.environ.get("""TESTING_MOCKED_DATALOADERS""",_UpperCAmelCase     ) == "1":
            _A							:     Any			=						2
      # Initialize accelerator
      _A							:     str			=						Accelerator(cpu=args.cpu,mixed_precision=args.mixed_precision     )
      # Sample hyper-parameters for learning rate, batch size, seed and a few other HPs
      _A							:     str			=						config['lr']
      _A							:     Dict			=						int(config["""num_epochs"""]     )
      _A							:     int			=						int(config["""seed"""]     )
      _A							:     int			=						int(config["""batch_size"""]     )

      _A							:     str			=						evaluate.load("""glue""","""mrpc"""     )

      # New Code #
      # We now can define an inner training loop function. It should take a batch size as the only parameter,
      # and build the dataloaders in there.
      # It also gets our decorator
      @find_executable_batch_size(starting_batch_size=_UpperCAmelCase     )
      def inner_training_loop(snake_case_     ):
            # And now just move everything below under this function
            # We need to bring in the Accelerator object from earlier
            nonlocal accelerator
            # And reset all of its attributes that could hold onto any memory:
            accelerator.free_memory()

            # Then we can declare the model, optimizer, and everything else:
            set_seed(_UpperCAmelCase     )

            # Instantiate the model (we build the model here so that the seed also control new weights initialization)
            _A							:     Tuple			=						AutoModelForSequenceClassification.from_pretrained("""bert-base-cased""",return_dict=_UpperCAmelCase     )

            # We could avoid this line since the accelerator is set with `device_placement=True` (default value).
            # Note that if you are placing tensors on devices manually, this line absolutely needs to be before the optimizer
            # creation otherwise training will not work on TPU (`accelerate` will kindly throw an error to make us aware of that).
            _A							:     List[Any]			=						model.to(accelerator.device     )

            # Instantiate optimizer
            _A							:     List[Any]			=						AdamW(params=model.parameters(),lr=_UpperCAmelCase     )
            _A							:     Tuple			=						get_dataloaders(_UpperCAmelCase,_UpperCAmelCase     )

            # Instantiate scheduler
            _A							:     Union[str, Any]			=						get_linear_schedule_with_warmup(
                optimizer=_UpperCAmelCase,num_warmup_steps=100,num_training_steps=(len(_UpperCAmelCase     ) * num_epochs),)

            # Prepare everything
            # There is no specific order to remember, we just need to unpack the objects in the same order we gave them to the
            # prepare method.
            _A							:     Optional[Any]			=						accelerator.prepare(
                _UpperCAmelCase,_UpperCAmelCase,_UpperCAmelCase,_UpperCAmelCase,_UpperCAmelCase     )

            # Now we train the model
            for epoch in range(_UpperCAmelCase     ):
                  model.train()
                  for step, batch in enumerate(_UpperCAmelCase     ):
                        # We could avoid this line since we set the accelerator with `device_placement=True`.
                        batch.to(accelerator.device     )
                        _A							:     List[str]			=						model(**_UpperCAmelCase     )
                        _A							:     Union[str, Any]			=						outputs.loss
                        accelerator.backward(_UpperCAmelCase     )
                        optimizer.step()
                        lr_scheduler.step()
                        optimizer.zero_grad()

                  model.eval()
                  for step, batch in enumerate(_UpperCAmelCase     ):
                        # We could avoid this line since we set the accelerator with `device_placement=True`.
                        batch.to(accelerator.device     )
                        with torch.no_grad():
                              _A							:     List[str]			=						model(**_UpperCAmelCase     )
                        _A							:     Union[str, Any]			=						outputs.logits.argmax(dim=-1     )
                        _A							:     int			=						accelerator.gather_for_metrics((predictions, batch["""labels"""])     )
                        metric.add_batch(
                            predictions=_UpperCAmelCase,references=_UpperCAmelCase,)

                  _A							:     Tuple			=						metric.compute()
                  # Use accelerator.print to print only on the main process.
                  accelerator.print(f'''epoch {epoch}:''',_UpperCAmelCase     )

    # New Code #
    # And call it at the end with no arguments
    # Note: You could also refactor this outside of your training loop function
      inner_training_loop()







def 				lowerCAmelCase_	(     ):
      _A							:     Dict			=						argparse.ArgumentParser(description="""Simple example of training script."""     )
      parser.add_argument(
          """--mixed_precision""",type=_UpperCAmelCase,default=_UpperCAmelCase,choices=["""no""", """fp16""", """bf16""", """fp8"""],help="""Whether to use mixed precision. Choose"""
          """between fp16 and bf16 (bfloat16). Bf16 requires PyTorch >= 1.10."""
          """and an Nvidia Ampere GPU.""",)
      parser.add_argument("""--cpu""",action="""store_true""",help="""If passed, will train on the CPU."""     )
      _A							:     Union[str, Any]			=						parser.parse_args()
      _A							:     int			=						{'lr': 2e-5, 'num_epochs': 3, 'seed': 42, 'batch_size': 16}
      training_function(_UpperCAmelCase,_UpperCAmelCase     )


if __name__ == "__main__":
  main()








import os
import tempfile
from functools import partial
from unittest import TestCase
from unittest.mock import patch

import numpy as np
import pytest

from datasets.arrow_dataset import Dataset
from datasets.search import ElasticSearchIndex, FaissIndex, MissingIndex

from .utils import require_elasticsearch, require_faiss


_UpperCAmelCase				:       str	   =				pytest.mark.integration

@require_faiss
class    lowerCAmelCase							(					__UpperCamelCase			):
 def      A_	(      self  :      List[Any]	)			->	Union[str, Any]:
     lowerCamelCase__    :      List[Any]					 =		Dataset.from_dict({'filename': ['my_name-train' + '_' + str(UpperCAmelCase	) for x in np.arange(30	).tolist()]}	)
     return dset
 def      A_	(      self  :      Optional[Any]	)			->	Optional[int]:
     import faiss

     lowerCamelCase__    :      Dataset					 =		self._create_dummy_dataset()
     lowerCamelCase__    :      List[Any]					 =		dset.map(
         lambda UpperCAmelCase			,     UpperCAmelCase	: {"vecs": i * np.ones(5			,     dtype=np.floataa	)}			,     with_indices=UpperCAmelCase			,     keep_in_memory=UpperCAmelCase	)
     lowerCamelCase__    :      Tuple					 =		dset.add_faiss_index('vecs'			,     batch_size=100			,     metric_type=faiss.METRIC_INNER_PRODUCT	)
     lowerCamelCase__ ,							lowerCamelCase__    :      str					 =		dset.get_nearest_examples('vecs'			,     np.ones(5			,     dtype=np.floataa	)	)
     self.assertEqual(examples['filename'][0]			,     'my_name-train_29'	)
     dset.drop_index('vecs'	)
 def      A_	(      self  :      Union[str, Any]	)			->	int:
     import faiss

     lowerCamelCase__    :      Dataset					 =		self._create_dummy_dataset()
     dset.add_faiss_index_from_external_arrays(
         external_arrays=np.ones((30, 5)	) * np.arange(30	).reshape(-1			,     1	)			,     index_name='vecs'			,     batch_size=100			,     metric_type=faiss.METRIC_INNER_PRODUCT			,     )
     lowerCamelCase__ ,							lowerCamelCase__    :      Optional[Any]					 =		dset.get_nearest_examples('vecs'			,     np.ones(5			,     dtype=np.floataa	)	)
     self.assertEqual(examples['filename'][0]			,     'my_name-train_29'	)
 def      A_	(      self  :      List[str]	)			->	Tuple:
     import faiss

     lowerCamelCase__    :      Dataset					 =		self._create_dummy_dataset()
     dset.add_faiss_index_from_external_arrays(
         external_arrays=np.ones((30, 5)	) * np.arange(30	).reshape(-1			,     1	)			,     index_name='vecs'			,     metric_type=faiss.METRIC_INNER_PRODUCT			,     )

     # Setting delete=False and unlinking manually is not pretty... but it is required on Windows to
     # ensure somewhat stable behaviour. If we don't, we get PermissionErrors. This is an age-old issue.
     # see https://bugs.python.org/issue14243 and
     # https://stackoverflow.com/questions/23212435/permission-denied-to-write-to-my-temporary-file/23212515
     with tempfile.NamedTemporaryFile(delete=UpperCAmelCase	) as tmp_file:
         dset.save_faiss_index('vecs'			,     tmp_file.name	)
         dset.load_faiss_index('vecs2'			,     tmp_file.name	)
     os.unlink(tmp_file.name	)

     lowerCamelCase__ ,							lowerCamelCase__    :      str					 =		dset.get_nearest_examples('vecs2'			,     np.ones(5			,     dtype=np.floataa	)	)
     self.assertEqual(examples['filename'][0]			,     'my_name-train_29'	)
 def      A_	(      self  :      Any	)			->	Optional[Any]:
     lowerCamelCase__    :      Dataset					 =		self._create_dummy_dataset()
     dset.add_faiss_index_from_external_arrays(
         external_arrays=np.ones((30, 5)	) * np.arange(30	).reshape(-1			,     1	)			,     index_name='vecs'	)
     dset.drop_index('vecs'	)
     self.assertRaises(UpperCAmelCase			,     partial(dset.get_nearest_examples			,     'vecs2'			,     np.ones(5			,     dtype=np.floataa	)	)	)







 def      A_	(      self  :      Dict	)			->	Dict:
     from elasticsearch import Elasticsearch

     lowerCamelCase__    :      Dataset					 =		self._create_dummy_dataset()
     with patch('elasticsearch.Elasticsearch.search'	) as mocked_search, patch(
         'elasticsearch.client.IndicesClient.create'	) as mocked_index_create, patch('elasticsearch.helpers.streaming_bulk'	) as mocked_bulk:
         lowerCamelCase__    :      List[Any]					 =		{'acknowledged': True}
         mocked_bulk.return_value([(True, None)] * 30	)
         lowerCamelCase__    :      int					 =		{'hits': {'hits': [{'_score': 1, '_id': 29}]}}
         lowerCamelCase__    :      List[str]					 =		Elasticsearch()

         dset.add_elasticsearch_index('filename'			,     es_client=UpperCAmelCase	)
         lowerCamelCase__ ,							lowerCamelCase__    :      Dict					 =		dset.get_nearest_examples('filename'			,     'my_name-train_29'	)
         self.assertEqual(examples['filename'][0]			,     'my_name-train_29'	)


@require_faiss
class    lowerCAmelCase							(					__UpperCamelCase			):
 def      A_	(      self  :      Any	)			->	Dict:
     import faiss

     lowerCamelCase__    :      Tuple					 =		FaissIndex(metric_type=faiss.METRIC_INNER_PRODUCT	)

     # add vectors
     index.add_vectors(np.eye(5			,     dtype=np.floataa	)	)
     self.assertIsNotNone(index.faiss_index	)
     self.assertEqual(index.faiss_index.ntotal			,     5	)
     index.add_vectors(np.zeros((5, 5)			,     dtype=np.floataa	)	)
     self.assertEqual(index.faiss_index.ntotal			,     10	)

     # single query
     lowerCamelCase__    :      int					 =		np.zeros(5			,     dtype=np.floataa	)
     lowerCamelCase__    :      Any					 =		1
     lowerCamelCase__ ,							lowerCamelCase__    :      Union[str, Any]					 =		index.search(UpperCAmelCase	)
     self.assertRaises(UpperCAmelCase			,     index.search			,     query.reshape(-1			,     1	)	)
     self.assertGreater(scores[0]			,     0	)
     self.assertEqual(indices[0]			,     1	)

     # batched queries
     lowerCamelCase__    :      str					 =		np.eye(5			,     dtype=np.floataa	)[::-1]
     lowerCamelCase__ ,							lowerCamelCase__    :      Dict					 =		index.search_batch(UpperCAmelCase	)
     self.assertRaises(UpperCAmelCase			,     index.search_batch			,     queries[0]	)
     lowerCamelCase__    :      str					 =		[scores[0] for scores in total_scores]
     lowerCamelCase__    :      List[str]					 =		[indices[0] for indices in total_indices]
     self.assertGreater(np.min(UpperCAmelCase	)			,     0	)
     self.assertListEqual([4, 3, 2, 1, 0]			,     UpperCAmelCase	)
 def      A_	(      self  :      List[Any]	)			->	List[Any]:
     import faiss

     lowerCamelCase__    :      Any					 =		FaissIndex(string_factory='Flat'	)
     index.add_vectors(np.eye(5			,     dtype=np.floataa	)	)
     self.assertIsInstance(index.faiss_index			,     faiss.IndexFlat	)
     lowerCamelCase__    :      Tuple					 =		FaissIndex(string_factory='LSH'	)
     index.add_vectors(np.eye(5			,     dtype=np.floataa	)	)
     self.assertIsInstance(index.faiss_index			,     faiss.IndexLSH	)
     with self.assertRaises(UpperCAmelCase	):
         lowerCamelCase__    :      List[str]					 =		FaissIndex(string_factory='Flat'			,     custom_index=faiss.IndexFlat(5	)	)
 def      A_	(      self  :      List[str]	)			->	Optional[int]:
     import faiss

     lowerCamelCase__    :      Optional[Any]					 =		faiss.IndexFlat(5	)
     lowerCamelCase__    :      int					 =		FaissIndex(custom_index=UpperCAmelCase	)
     index.add_vectors(np.eye(5			,     dtype=np.floataa	)	)
     self.assertIsInstance(index.faiss_index			,     faiss.IndexFlat	)







 def      A_	(      self  :      Any	)			->	Optional[int]:
     import faiss

     lowerCamelCase__    :      Any					 =		FaissIndex(metric_type=faiss.METRIC_INNER_PRODUCT	)
     index.add_vectors(np.eye(5			,     dtype=np.floataa	)	)

     # Setting delete=False and unlinking manually is not pretty... but it is required on Windows to
     # ensure somewhat stable behaviour. If we don't, we get PermissionErrors. This is an age-old issue.
     # see https://bugs.python.org/issue14243 and
     # https://stackoverflow.com/questions/23212435/permission-denied-to-write-to-my-temporary-file/23212515
     with tempfile.NamedTemporaryFile(delete=UpperCAmelCase	) as tmp_file:
         index.save(tmp_file.name	)
         lowerCamelCase__    :      List[Any]					 =		FaissIndex.load(tmp_file.name	)
     os.unlink(tmp_file.name	)

     lowerCamelCase__    :      List[str]					 =		np.zeros(5			,     dtype=np.floataa	)
     lowerCamelCase__    :      Tuple					 =		1
     lowerCamelCase__ ,							lowerCamelCase__    :      str					 =		index.search(UpperCAmelCase	)
     self.assertGreater(scores[0]			,     0	)
     self.assertEqual(indices[0]			,     1	)


@require_faiss
def        SCREAMING_SNAKE_CASE      (       _UpperCAmelCase )			->     Any:
    import faiss

    lowerCamelCase__    :      Optional[Any]					 =		FaissIndex(metric_type=faiss.METRIC_INNER_PRODUCT )
    index.add_vectors(np.eye(5						,	dtype=np.floataa ) )

    lowerCamelCase__    :      Optional[int]					 =		'index.faiss'
    lowerCamelCase__    :      Optional[Any]					 =		F"""mock://{index_name}"""
    index.save(_UpperCAmelCase						,	storage_options=mockfs.storage_options )
    lowerCamelCase__    :      Tuple					 =		FaissIndex.load(_UpperCAmelCase						,	storage_options=mockfs.storage_options )

    lowerCamelCase__    :      Optional[int]					 =		np.zeros(5						,	dtype=np.floataa )
    lowerCamelCase__    :      Dict					 =		1
    lowerCamelCase__ ,							lowerCamelCase__    :      str					 =		index.search(_UpperCAmelCase )
    assert scores[0] > 0
    assert indices[0] == 1


@require_elasticsearch
class    lowerCAmelCase							(					__UpperCamelCase			):
 def      A_	(      self  :      Dict	)			->	List[Any]:
     from elasticsearch import Elasticsearch

     with patch('elasticsearch.Elasticsearch.search'	) as mocked_search, patch(
         'elasticsearch.client.IndicesClient.create'	) as mocked_index_create, patch('elasticsearch.helpers.streaming_bulk'	) as mocked_bulk:
         lowerCamelCase__    :      Any					 =		Elasticsearch()
         lowerCamelCase__    :      Tuple					 =		{'acknowledged': True}
         lowerCamelCase__    :      Tuple					 =		ElasticSearchIndex(es_client=UpperCAmelCase	)
         mocked_bulk.return_value([(True, None)] * 3	)
         index.add_documents(['foo', 'bar', 'foobar']	)

         # single query
         lowerCamelCase__    :      Optional[int]					 =		'foo'
         lowerCamelCase__    :      str					 =		{'hits': {'hits': [{'_score': 1, '_id': 0}]}}
         lowerCamelCase__ ,							lowerCamelCase__    :      Optional[Any]					 =		index.search(UpperCAmelCase	)
         self.assertEqual(scores[0]			,     1	)
         self.assertEqual(indices[0]			,     0	)

         # single query with timeout
         lowerCamelCase__    :      Any					 =		'foo'
         lowerCamelCase__    :      List[str]					 =		{'hits': {'hits': [{'_score': 1, '_id': 0}]}}
         lowerCamelCase__ ,							lowerCamelCase__    :      Tuple					 =		index.search(UpperCAmelCase			,     request_timeout=30	)
         self.assertEqual(scores[0]			,     1	)
         self.assertEqual(indices[0]			,     0	)

         # batched queries
         lowerCamelCase__    :      List[str]					 =		['foo', 'bar', 'foobar']
         lowerCamelCase__    :      str					 =		{'hits': {'hits': [{'_score': 1, '_id': 1}]}}
         lowerCamelCase__ ,							lowerCamelCase__    :      str					 =		index.search_batch(UpperCAmelCase	)
         lowerCamelCase__    :      List[str]					 =		[scores[0] for scores in total_scores]
         lowerCamelCase__    :      List[Any]					 =		[indices[0] for indices in total_indices]
         self.assertGreater(np.min(UpperCAmelCase	)			,     0	)
         self.assertListEqual([1, 1, 1]			,     UpperCAmelCase	)

         # batched queries with timeout
         lowerCamelCase__    :      str					 =		['foo', 'bar', 'foobar']
         lowerCamelCase__    :      List[Any]					 =		{'hits': {'hits': [{'_score': 1, '_id': 1}]}}
         lowerCamelCase__ ,							lowerCamelCase__    :      Optional[Any]					 =		index.search_batch(UpperCAmelCase			,     request_timeout=30	)
         lowerCamelCase__    :      Optional[Any]					 =		[scores[0] for scores in total_scores]
         lowerCamelCase__    :      Dict					 =		[indices[0] for indices in total_indices]
         self.assertGreater(np.min(UpperCAmelCase	)			,     0	)
         self.assertListEqual([1, 1, 1]			,     UpperCAmelCase	)





