class_docstr: `BetterTransformersTestMixin` to wrap necessary functions for testing `BetterTransformer`
  integration. This includes the following tests:
      - `test_logits`: This tests if the converted model produces the same logits
      than the original model.
      - `test_raise_on_save`: Test if the converion properly raises an error if someone tries to save the model using `save_pretrained`.
class_docstr_tok: ["`","BetterTransformersTestMixin","`","to","wrap","necessary","functions","for","testing","`","BetterTransformer","`","integration",".","This","includes","the","following","tests",":","-","`","test_logits","`",":","This","tests","if","the","converted","model","produces","the","same","logits","than","the","original","model",".","-","`","test_raise_on_save","`",":","Test","if","the","converion","properly","raises","an","error","if","someone","tries","to","save","the","model","using","`","save_pretrained","`","."]
code: def _test_logits_backward(
      self, model_id: str, model_type: str, **preprocessor_kwargs
  ):
      inputs = self.prepare_inputs_for_class(
          model_id=model_id,
          model_type=model_type,
          **preprocessor_kwargs,
      )
  
      hf_random_model = AutoModel.from_pretrained(model_id).eval()
      random_config = hf_random_model.config
  
      # I could not obtain reproducible results with `torch.manual_seed` nor with
      # `torch.random.set_rng_state`. An alternative could be to make dropout stateful,
      # and to replace them with a static pattern for this test. Currently, we use
      # functional dropout though.
      # We need to be in train mode to take the right path.
      random_config = set_dropout_to_zero(random_config)
  
      # m2m_100 randomly drops layers, which makes testing flaky (see `skip_the_layer` in transformers, some other models use it as well)
      if model_type == "m2m_100":
          random_config.encoder_layerdrop = 0
          random_config.decoder_layerdrop = 0
  
      hf_random_model = hf_random_model.__class__(random_config)
  
      converted_model = copy.deepcopy(hf_random_model)
      converted_model = BetterTransformer.transform(converted_model)
  
      hf_random_model = hf_random_model.train()
      converted_model = converted_model.train()
  
      optimizer_hf = torch.optim.SGD(
          hf_random_model.parameters(), lr=0.2
      )
      optimizer_bt = torch.optim.SGD(
          converted_model.parameters(), lr=0.2
      )
  
      tol = 2e-3
  
      hf_hidden_states = hf_random_model(**inputs)[0]
      bt_hidden_states = converted_model(**inputs)[0]
  
      self.assert_equal(
          hf_hidden_states,
          bt_hidden_states,
          atol=tol,
          model_name=hf_random_model.__class__.__name__,
      )
  
      loss_hf = hf_hidden_states.abs().mean()
      loss_bt = bt_hidden_states.abs().mean()
  
      loss_hf.backward()
      loss_bt.backward()
  
      optimizer_hf.step()
      optimizer_bt.step()
  
      hf_hidden_states = hf_random_model(**inputs)[0]
      bt_hidden_states = converted_model(**inputs)[0]
  
      self.assert_equal(
          hf_hidden_states,
          bt_hidden_states,
          atol=tol,
          model_name=hf_random_model.__class__.__name__,
      )
  
imports: import copy
  import inspect
  import tempfile
  import unittest
  import torch
  from transformers import AutoModel
  from optimum.bettertransformer import BetterTransformer
  from optimum.utils.testing_utils import flatten_dict, require_torch_gpu
label_desc: Use image node_id 3 for calling the BetterTransformersTestMixin obj's underlying member method code with example usage: obj._test_logits_backward(model_id, model_type) without return types