import inspect
import unittest

from transformers import DecisionTransformerConfig, is_torch_available
from transformers.testing_utils import require_torch, slow, torch_device

from ...generation.test_utils import GenerationTesterMixin
from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor, random_attention_mask
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
					import torch

					from transformers import DecisionTransformerModel
					from transformers.models.decision_transformer.modeling_decision_transformer import (
					    DECISION_TRANSFORMER_PRETRAINED_MODEL_ARCHIVE_LIST,
					)





class       lowercase__		:


						def __init__( self			:       Dict					,	UpperCamelCase__			:       Dict					,	UpperCamelCase__			:       Any=13					,	UpperCamelCase__			:       Any=7					,	UpperCamelCase__			:       Tuple=6					,	UpperCamelCase__			:       int=17					,	UpperCamelCase__			:       List[str]=23					,	UpperCamelCase__			:       Optional[Any]=11					,	UpperCamelCase__			:       List[Any]=True					,	):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					Optional[int]           =							parent
												SCREAMING_SNAKE_CASE							:					Optional[int]           =							batch_size
												SCREAMING_SNAKE_CASE							:					Any           =							seq_length
												SCREAMING_SNAKE_CASE							:					int           =							act_dim
												SCREAMING_SNAKE_CASE							:					Any           =							state_dim
												SCREAMING_SNAKE_CASE							:					Dict           =							hidden_size
												SCREAMING_SNAKE_CASE							:					Optional[Any]           =							max_length
												SCREAMING_SNAKE_CASE							:					List[Any]           =							is_training


						def  __A ( self			:       Any		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					Tuple           =							floats_tensor((self.batch_size, self.seq_length, self.state_dim)		)
												SCREAMING_SNAKE_CASE							:					Tuple           =							floats_tensor((self.batch_size, self.seq_length, self.act_dim)		)
												SCREAMING_SNAKE_CASE							:					Dict           =							floats_tensor((self.batch_size, self.seq_length, 1)		)
												SCREAMING_SNAKE_CASE							:					Optional[int]           =							floats_tensor((self.batch_size, self.seq_length, 1)		)
												SCREAMING_SNAKE_CASE							:					str           =							ids_tensor((self.batch_size, self.seq_length)					,	vocab_size=1000		)
												SCREAMING_SNAKE_CASE							:					List[str]           =							random_attention_mask((self.batch_size, self.seq_length)		)

												SCREAMING_SNAKE_CASE							:					List[str]           =							self.get_config()

												return (
												    config,
												    states,
												    actions,
												    rewards,
												    returns_to_go,
												    timesteps,
												    attention_mask,
												)


						def  __A ( self			:       Dict		):





												'''simple docstring'''





												return DecisionTransformerConfig(
												    batch_size=self.batch_size					,	seq_length=self.seq_length					,	act_dim=self.act_dim					,	state_dim=self.state_dim					,	hidden_size=self.hidden_size					,	max_length=self.max_length					,	)


						def  __A ( self			:       str					,	UpperCamelCase__			:       Any					,	UpperCamelCase__			:       Dict					,	UpperCamelCase__			:       str					,	UpperCamelCase__			:       Union[str, Any]					,	UpperCamelCase__			:       Tuple					,	UpperCamelCase__			:       List[Any]					,	UpperCamelCase__			:       Dict					,	):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					Tuple           =							DecisionTransformerModel(config=UpperCamelCase__		)
												model.to(UpperCamelCase__		)
												model.eval()
												SCREAMING_SNAKE_CASE							:					List[str]           =							model(UpperCamelCase__					,	UpperCamelCase__					,	UpperCamelCase__					,	UpperCamelCase__					,	UpperCamelCase__					,	UpperCamelCase__		)

												self.parent.assertEqual(result.state_preds.shape					,	states.shape		)
												self.parent.assertEqual(result.action_preds.shape					,	actions.shape		)
												self.parent.assertEqual(result.return_preds.shape					,	returns_to_go.shape		)
												self.parent.assertEqual(
												    result.last_hidden_state.shape					,	(self.batch_size, self.seq_length * 3, self.hidden_size)		)  # seq length *3 as there are 3 modelities: states, returns and actions



						def  __A ( self			:       Optional[Any]		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					Dict           =							self.prepare_config_and_inputs()
												(
												    SCREAMING_SNAKE_CASE						
												)							:					Union[str, Any]           =							config_and_inputs
												SCREAMING_SNAKE_CASE							:					Optional[Any]           =							{
												    '''states''': states,
												    '''actions''': actions,
												    '''rewards''': rewards,
												    '''returns_to_go''': returns_to_go,
												    '''timesteps''': timesteps,
												    '''attention_mask''': attention_mask,
												}
												return config, inputs_dict






@require_torch
class       lowercase__		(     UpperCamelCase_			,							UpperCamelCase_			,							UpperCamelCase_			,							unittest.TestCase):
						UpperCamelCase_  =	(DecisionTransformerModel,) if is_torch_available() else ()
						UpperCamelCase_  =	()
						UpperCamelCase_  =	{"""feature-extraction""": DecisionTransformerModel} if is_torch_available() else {}

						# Ignoring of a failing test from GenerationTesterMixin, as the model does not use inputs_ids
						UpperCamelCase_  =	False

						# Ignoring of a failing tests from ModelTesterMixin, as the model does not implement these features
						UpperCamelCase_  =	False
						UpperCamelCase_  =	False
						UpperCamelCase_  =	False
						UpperCamelCase_  =	False
						UpperCamelCase_  =	False
						UpperCamelCase_  =	False
						UpperCamelCase_  =	False
						UpperCamelCase_  =	False
						UpperCamelCase_  =	False


						def  __A ( self			:       List[str]		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					List[Any]           =							DecisionTransformerModelTester(self		)
												SCREAMING_SNAKE_CASE							:					Any           =							ConfigTester(self					,	config_class=UpperCamelCase__					,	hidden_size=37		)


						def  __A ( self			:       int		):





												'''simple docstring'''





												self.config_tester.run_common_tests()


						def  __A ( self			:       Optional[Any]		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					Tuple           =							self.model_tester.prepare_config_and_inputs()
												self.model_tester.create_and_check_model(*UpperCamelCase__		)


						@slow
						def  __A ( self			:       Optional[Any]		):





												'''simple docstring'''





												for model_name in DECISION_TRANSFORMER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
																		SCREAMING_SNAKE_CASE							:					List[str]           =							DecisionTransformerModel.from_pretrained(UpperCamelCase__		)
																		self.assertIsNotNone(UpperCamelCase__		)



						def  __A ( self			:       Dict		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					Tuple           =							self.model_tester.prepare_config_and_inputs_for_common()

												for model_class in self.all_model_classes:
																		SCREAMING_SNAKE_CASE							:					int           =							model_class(UpperCamelCase__		)
																		SCREAMING_SNAKE_CASE							:					Any           =							inspect.signature(model.forward		)
																		# signature.parameters is an OrderedDict => so arg_names order is deterministic
																		SCREAMING_SNAKE_CASE							:					str           =							[*signature.parameters.keys()]

																		SCREAMING_SNAKE_CASE							:					str           =							[
																		    '''states''',
																		    '''actions''',
																		    '''rewards''',
																		    '''returns_to_go''',
																		    '''timesteps''',
																		    '''attention_mask''',
																		]

																		self.assertListEqual(arg_names[: len(UpperCamelCase__		)]					,	UpperCamelCase__		)






@require_torch
class       lowercase__		(     unittest.TestCase):


						@slow
						def  __A ( self			:       Dict		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					str           =							2  # number of steps of autoregressive prediction we will perform
												SCREAMING_SNAKE_CASE							:					Tuple           =							10  # defined by the RL environment, may be normalized
												SCREAMING_SNAKE_CASE							:					Optional[int]           =							DecisionTransformerModel.from_pretrained('''edbeeching/decision-transformer-gym-hopper-expert'''		)
												SCREAMING_SNAKE_CASE							:					Any           =							model.to(UpperCamelCase__		)
												SCREAMING_SNAKE_CASE							:					int           =							model.config
												torch.manual_seed(0		)
												SCREAMING_SNAKE_CASE							:					Any           =							torch.randn(1					,	1					,	config.state_dim		).to(device=UpperCamelCase__					,	dtype=torch.floataa		)  # env.reset()

												SCREAMING_SNAKE_CASE							:					Optional[int]           =							torch.tensor(
												    [[0.24_2793, -0.2869_3074, 0.874_2613], [0.6781_5274, -0.0810_1085, -0.1295_2147]]					,	device=UpperCamelCase__		)

												SCREAMING_SNAKE_CASE							:					Tuple           =							torch.tensor(UpperCamelCase__					,	device=UpperCamelCase__					,	dtype=torch.floataa		).reshape(1					,	1					,	1		)
												SCREAMING_SNAKE_CASE							:					Optional[int]           =							state
												SCREAMING_SNAKE_CASE							:					Any           =							torch.zeros(1					,	0					,	config.act_dim					,	device=UpperCamelCase__					,	dtype=torch.floataa		)
												SCREAMING_SNAKE_CASE							:					int           =							torch.zeros(1					,	0					,	device=UpperCamelCase__					,	dtype=torch.floataa		)
												SCREAMING_SNAKE_CASE							:					Any           =							torch.tensor(0					,	device=UpperCamelCase__					,	dtype=torch.long		).reshape(1					,	1		)

												for step in range(UpperCamelCase__		):
																		SCREAMING_SNAKE_CASE							:					str           =							torch.cat([actions, torch.zeros(1					,	1					,	config.act_dim					,	device=UpperCamelCase__		)]					,	dim=1		)
																		SCREAMING_SNAKE_CASE							:					Union[str, Any]           =							torch.cat([rewards, torch.zeros(1					,	1					,	device=UpperCamelCase__		)]					,	dim=1		)

																		SCREAMING_SNAKE_CASE							:					Tuple           =							torch.ones(1					,	states.shape[1]		).to(dtype=torch.long					,	device=states.device		)

																		with torch.no_grad():
																								SCREAMING_SNAKE_CASE							:					str           =							model(
																								    states=UpperCamelCase__					,	actions=UpperCamelCase__					,	rewards=UpperCamelCase__					,	returns_to_go=UpperCamelCase__					,	timesteps=UpperCamelCase__					,	attention_mask=UpperCamelCase__					,	return_dict=UpperCamelCase__					,	)

																		self.assertEqual(action_pred.shape					,	actions.shape		)
																		self.assertTrue(torch.allclose(action_pred[0, -1]					,	expected_outputs[step]					,	atol=1E-4		)		)
																		SCREAMING_SNAKE_CASE							:					str           =							(  # env.step(action)
																		    torch.randn(1					,	1					,	config.state_dim		).to(device=UpperCamelCase__					,	dtype=torch.floataa		),
																		    1.0,
																		    False,
																		    {},
																		)

																		SCREAMING_SNAKE_CASE							:					Optional[Any]           =							action_pred[0, -1]
																		SCREAMING_SNAKE_CASE							:					Tuple           =							torch.cat([states, state]					,	dim=1		)
																		SCREAMING_SNAKE_CASE							:					Tuple           =							returns_to_go[0, -1] - reward
																		SCREAMING_SNAKE_CASE							:					List[Any]           =							torch.cat([returns_to_go, pred_return.reshape(1					,	1					,	1		)]					,	dim=1		)
																		SCREAMING_SNAKE_CASE							:					List[str]           =							torch.cat(
																		    [timesteps, torch.ones((1, 1)					,	device=UpperCamelCase__					,	dtype=torch.long		) * (step + 1)]					,	dim=1		)






import numpy as np
import torch
from torch.utils.data import Dataset, IterableDataset

from ..utils.generic import ModelOutput





class       lowercase__		(     UpperCamelCase_):


						def __init__( self			:       str					,	UpperCamelCase__			:       Optional[int]					,	UpperCamelCase__			:       Optional[int]					,	UpperCamelCase__			:       Optional[Any]		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					Union[str, Any]           =							dataset
												SCREAMING_SNAKE_CASE							:					Optional[Any]           =							process
												SCREAMING_SNAKE_CASE							:					Union[str, Any]           =							params


						def __len__( self			:       Tuple		):





												'''simple docstring'''





												return len(self.dataset		)



						def __getitem__( self			:       List[str]					,	UpperCamelCase__			:       Optional[Any]		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					List[Any]           =							self.dataset[i]
												SCREAMING_SNAKE_CASE							:					Optional[int]           =							self.process(UpperCamelCase__					,	**self.params		)
												return processed






class       lowercase__		(     UpperCamelCase_):


						def __init__( self			:       Dict					,	UpperCamelCase__			:       Union[str, Any]					,	UpperCamelCase__			:       Optional[int]					,	UpperCamelCase__			:       Dict					,	UpperCamelCase__			:       List[Any]=None		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					List[Any]           =							loader
												SCREAMING_SNAKE_CASE							:					List[Any]           =							infer
												SCREAMING_SNAKE_CASE							:					int           =							params
												if loader_batch_size == 1:
																		# Let's spare some time by deactivating altogether
																		SCREAMING_SNAKE_CASE							:					Optional[int]           =							None
												SCREAMING_SNAKE_CASE							:					List[str]           =							loader_batch_size

												# Internal bookkeeping
												SCREAMING_SNAKE_CASE							:					Optional[int]           =							None
												SCREAMING_SNAKE_CASE							:					int           =							None


						def __len__( self			:       int		):





												'''simple docstring'''





												return len(self.loader		)


						def __iter__( self			:       List[str]		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					Optional[int]           =							iter(self.loader		)
												return self


						def  __A ( self			:       List[str]		):





												'''simple docstring'''





												if isinstance(self._loader_batch_data					,	torch.Tensor		):
																		# Batch data is simple tensor, just fetch the slice
																		SCREAMING_SNAKE_CASE							:					Optional[Any]           =							self._loader_batch_data[self._loader_batch_index]
												else:
																		# Batch data is assumed to be BaseModelOutput (or dict)
																		SCREAMING_SNAKE_CASE							:					Union[str, Any]           =							{}
																		for k, element in self._loader_batch_data.items():
																								if isinstance(UpperCamelCase__					,	UpperCamelCase__		):
																														# Convert ModelOutput to tuple first
																														SCREAMING_SNAKE_CASE							:					Dict           =							element.to_tuple()
																														if isinstance(element[0]					,	torch.Tensor		):
																																				SCREAMING_SNAKE_CASE							:					Dict           =							tuple(el[self._loader_batch_index].unsqueeze(0		) for el in element		)
																														elif isinstance(element[0]					,	np.ndarray		):
																																				SCREAMING_SNAKE_CASE							:					Union[str, Any]           =							tuple(np.expand_dims(el[self._loader_batch_index]					,	0		) for el in element		)
																														continue
																								if k in {"hidden_states", "past_key_values", "attentions"} and isinstance(UpperCamelCase__					,	UpperCamelCase__		):
																														# Those are stored as lists of tensors so need specific unbatching.
																														if isinstance(element[0]					,	torch.Tensor		):
																																				SCREAMING_SNAKE_CASE							:					Union[str, Any]           =							tuple(el[self._loader_batch_index].unsqueeze(0		) for el in element		)
																														elif isinstance(element[0]					,	np.ndarray		):
																																				SCREAMING_SNAKE_CASE							:					List[str]           =							tuple(np.expand_dims(el[self._loader_batch_index]					,	0		) for el in element		)
																														continue
																								if element is None:
																														# This can happen for optional data that get passed around
																														SCREAMING_SNAKE_CASE							:					int           =							None
																								elif isinstance(element[self._loader_batch_index]					,	torch.Tensor		):
																														# Take correct batch data, but make it looked like batch_size=1
																														# For compatibility with other methods within transformers

																														SCREAMING_SNAKE_CASE							:					Union[str, Any]           =							element[self._loader_batch_index].unsqueeze(0		)
																								elif isinstance(element[self._loader_batch_index]					,	np.ndarray		):
																														# Take correct batch data, but make it looked like batch_size=1
																														# For compatibility with other methods within transformers
																														SCREAMING_SNAKE_CASE							:					Tuple           =							np.expand_dims(element[self._loader_batch_index]					,	0		)
																								else:
																														# This is typically a list, so no need to `unsqueeze`.
																														SCREAMING_SNAKE_CASE							:					Tuple           =							element[self._loader_batch_index]
            # Recreate the element by reusing the original class to make it look
            # batch_size=1
																		SCREAMING_SNAKE_CASE							:					Any           =							self._loader_batch_data.__class__(UpperCamelCase__		)
												self._loader_batch_index += 1
												return result



						def  __A ( self			:       Union[str, Any]		):





												'''simple docstring'''





												if self._loader_batch_index is not None and self._loader_batch_index < self.loader_batch_size:
																		# We are currently unrolling a batch so we just need to return
																		# the current item within a batch
																		return self.loader_batch_item()

												# We're out of items within a batch
												SCREAMING_SNAKE_CASE							:					Tuple           =							next(self.iterator		)
												SCREAMING_SNAKE_CASE							:					List[Any]           =							self.infer(UpperCamelCase__					,	**self.params		)
												# We now have a batch of "inferred things".
												if self.loader_batch_size is not None:
																		# Try to infer the size of the batch
																		if isinstance(UpperCamelCase__					,	torch.Tensor		):
																								SCREAMING_SNAKE_CASE							:					Optional[int]           =							processed
																		else:
																								SCREAMING_SNAKE_CASE							:					int           =							list(processed.keys()		)[0]
																								SCREAMING_SNAKE_CASE							:					int           =							processed[key]
																		if isinstance(UpperCamelCase__					,	UpperCamelCase__		):
																								SCREAMING_SNAKE_CASE							:					List[Any]           =							len(UpperCamelCase__		)
																		else:
																								SCREAMING_SNAKE_CASE							:					Dict           =							first_tensor.shape[0]
																		if 0 < observed_batch_size < self.loader_batch_size:
																								# could be last batch so we can't unroll as many
																								# elements.
																								SCREAMING_SNAKE_CASE							:					List[Any]           =							observed_batch_size
																		# Setting internal index to unwrap the batch
																		SCREAMING_SNAKE_CASE							:					List[Any]           =							processed
																		SCREAMING_SNAKE_CASE							:					int           =							0
																		return self.loader_batch_item()
												else:
																		# We're not unrolling batches
																		return processed






class       lowercase__		(     UpperCamelCase_):


						def __init__( self			:       str					,	UpperCamelCase__			:       List[Any]					,	UpperCamelCase__			:       Optional[int]					,	UpperCamelCase__			:       Union[str, Any]					,	UpperCamelCase__			:       Union[str, Any]=None		):





												'''simple docstring'''





												super().__init__(UpperCamelCase__					,	UpperCamelCase__					,	UpperCamelCase__		)


						def __iter__( self			:       Union[str, Any]		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					Tuple           =							iter(self.loader		)
												SCREAMING_SNAKE_CASE							:					List[Any]           =							None
												return self



						def  __A ( self			:       List[str]		):





												'''simple docstring'''





												if self.subiterator is None:
																		SCREAMING_SNAKE_CASE							:					Dict           =							self.infer(next(self.iterator		)					,	**self.params		)
												try:
																		# Try to return next item
																		SCREAMING_SNAKE_CASE							:					Any           =							next(self.subiterator		)
												except StopIteration:
																		# When a preprocess iterator ends, we can start lookig at the next item
																		# ChunkIterator will keep feeding until ALL elements of iterator
																		# all have created their subiterator and have been iterating against.
																		#
																		# Another way to look at it, is we're basically flattening lists of lists
																		# into a single list, but with generators
																		SCREAMING_SNAKE_CASE							:					Optional[Any]           =							self.infer(next(self.iterator		)					,	**self.params		)
																		SCREAMING_SNAKE_CASE							:					Union[str, Any]           =							next(self.subiterator		)
												return processed






class       lowercase__		(     UpperCamelCase_):


						def __iter__( self			:       Tuple		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					Dict           =							iter(self.loader		)
												return self



						def  __A ( self			:       List[str]		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					List[Any]           =							False
												SCREAMING_SNAKE_CASE							:					Optional[int]           =							[]
												if self._loader_batch_index is not None and self._loader_batch_index < self.loader_batch_size:
																		while self._loader_batch_index < self.loader_batch_size:
																								SCREAMING_SNAKE_CASE							:					Tuple           =							self.loader_batch_item()
																								SCREAMING_SNAKE_CASE							:					Any           =							item.pop('''is_last'''		)
																								accumulator.append(UpperCamelCase__		)
																								if is_last:
																														return accumulator

												while not is_last:
																		SCREAMING_SNAKE_CASE							:					Any           =							self.infer(next(self.iterator		)					,	**self.params		)
																		if self.loader_batch_size is not None:
																								if isinstance(UpperCamelCase__					,	torch.Tensor		):
																														SCREAMING_SNAKE_CASE							:					Tuple           =							processed
																								else:
																														SCREAMING_SNAKE_CASE							:					Union[str, Any]           =							list(processed.keys()		)[0]
																														SCREAMING_SNAKE_CASE							:					List[str]           =							processed[key]
																								if isinstance(UpperCamelCase__					,	UpperCamelCase__		):
																														SCREAMING_SNAKE_CASE							:					List[Any]           =							len(UpperCamelCase__		)
																								else:
																														SCREAMING_SNAKE_CASE							:					int           =							first_tensor.shape[0]
																								if 0 < observed_batch_size < self.loader_batch_size:
																														# could be last batch so we can't unroll as many
																														# elements.
																														SCREAMING_SNAKE_CASE							:					List[str]           =							observed_batch_size
																								SCREAMING_SNAKE_CASE							:					List[Any]           =							processed
																								SCREAMING_SNAKE_CASE							:					str           =							0
																								while self._loader_batch_index < self.loader_batch_size:
																														SCREAMING_SNAKE_CASE							:					Any           =							self.loader_batch_item()
																														SCREAMING_SNAKE_CASE							:					List[Any]           =							item.pop('''is_last'''		)
																														accumulator.append(UpperCamelCase__		)
																														if is_last:
																																				return accumulator
																		else:
																								SCREAMING_SNAKE_CASE							:					int           =							processed
																								SCREAMING_SNAKE_CASE							:					List[str]           =							item.pop('''is_last'''		)
																								accumulator.append(UpperCamelCase__		)
												return accumulator






class       lowercase__		(     UpperCamelCase_):


						def __init__( self			:       Optional[Any]					,	UpperCamelCase__			:       Dataset					,	UpperCamelCase__			:       str		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					Optional[Any]           =							dataset
												SCREAMING_SNAKE_CASE							:					Dict           =							key


						def __len__( self			:       Optional[int]		):





												'''simple docstring'''





												return len(self.dataset		)



						def __getitem__( self			:       Dict					,	UpperCamelCase__			:       Tuple		):





												'''simple docstring'''





												return self.dataset[i][self.key]






class       lowercase__		(     UpperCamelCase_):


						def __init__( self			:       List[Any]					,	UpperCamelCase__			:       Dataset					,	UpperCamelCase__			:       str					,	UpperCamelCase__			:       str		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					str           =							dataset
												SCREAMING_SNAKE_CASE							:					List[str]           =							keya
												SCREAMING_SNAKE_CASE							:					Tuple           =							keya


						def __len__( self			:       List[str]		):





												'''simple docstring'''





												return len(self.dataset		)



						def __getitem__( self			:       Union[str, Any]					,	UpperCamelCase__			:       Any		):





												'''simple docstring'''





												return {"text": self.dataset[i][self.keya], "text_pair": self.dataset[i][self.keya]}





