



'''simple docstring'''





from typing import List, Optional

import numpy as np

from ...processing_utils import ProcessorMixin
from ...utils import to_numpy



class 	lowerCamelCase      (						lowercase__  ):







					'''simple docstring'''







					lowerCAmelCase_				:    str									=  'EncodecFeatureExtractor'
					lowerCAmelCase_				:    str									=  ('T5Tokenizer', 'T5TokenizerFast')



					def __init__(			self    ,	lowerCAmelCase    ,	lowerCAmelCase     ):
							super().__init__(lowerCAmelCase    ,	lowerCAmelCase     )
							UpperCAmelCase_						=				self.feature_extractor
							UpperCAmelCase_						=				False



					def    A__		(			self    ,	lowerCAmelCase=None    ,	lowerCAmelCase=None    ,	lowerCAmelCase=True     ):
							return self.tokenizer.get_decoder_prompt_ids(task=lowerCAmelCase    ,	language=lowerCAmelCase    ,	no_timestamps=lowerCAmelCase     )



					def __call__(			self    ,	*lowerCAmelCase    ,	**lowerCAmelCase     ):
							# For backward compatibility
							if self._in_target_context_manager:
									return self.current_processor(*lowerCAmelCase    ,	**lowerCAmelCase     )

							UpperCAmelCase_						=				kwargs.pop("audio"    ,	lowerCAmelCase     )
							UpperCAmelCase_						=				kwargs.pop("sampling_rate"    ,	lowerCAmelCase     )
							UpperCAmelCase_						=				kwargs.pop("text"    ,	lowerCAmelCase     )
							if len(lowerCAmelCase     ) > 0:
									UpperCAmelCase_						=				args[0]
									UpperCAmelCase_						=				args[1:]

							if audio is None and text is None:
									raise ValueError("You need to specify either an `audio` or `text` input to process."     )

							if text is not None:
									UpperCAmelCase_						=				self.tokenizer(lowerCAmelCase    ,	**lowerCAmelCase     )

							if audio is not None:
									UpperCAmelCase_						=				self.feature_extractor(lowerCAmelCase    ,	*lowerCAmelCase    ,	sampling_rate=lowerCAmelCase    ,	**lowerCAmelCase     )

							if audio is None:
									return inputs

							elif text is None:
									return audio_inputs

							else:
									UpperCAmelCase_						=				audio_inputs["input_values"]
									if "padding_mask" in audio_inputs:
											UpperCAmelCase_						=				audio_inputs["padding_mask"]
									return inputs



					def    A__		(			self    ,	*lowerCAmelCase    ,	**lowerCAmelCase     ):
							UpperCAmelCase_						=				kwargs.pop("audio"    ,	lowerCAmelCase     )
							UpperCAmelCase_						=				kwargs.pop("padding_mask"    ,	lowerCAmelCase     )

							if len(lowerCAmelCase     ) > 0:
									UpperCAmelCase_						=				args[0]
									UpperCAmelCase_						=				args[1:]

							if audio_values is not None:
									return self._decode_audio(lowerCAmelCase    ,	padding_mask=lowerCAmelCase     )
							else:
									return self.tokenizer.batch_decode(*lowerCAmelCase    ,	**lowerCAmelCase     )



					def    A__		(			self    ,	*lowerCAmelCase    ,	**lowerCAmelCase     ):
							return self.tokenizer.decode(*lowerCAmelCase    ,	**lowerCAmelCase     )



					def    A__		(			self    ,	lowerCAmelCase    ,	lowerCAmelCase = None     ):
							UpperCAmelCase_						=				to_numpy(lowerCAmelCase     )
							UpperCAmelCase_					,						UpperCAmelCase_					,						UpperCAmelCase_						=				audio_values.shape

							if padding_mask is None:
									return list(lowerCAmelCase     )

							UpperCAmelCase_						=				to_numpy(lowerCAmelCase     )

							# match the sequence length of the padding mask to the generated audio arrays by padding with the **non-padding**
							# token (so that the generated audio values are **not** treated as padded tokens)
							UpperCAmelCase_						=				seq_len - padding_mask.shape[-1]
							UpperCAmelCase_						=				1 - self.feature_extractor.padding_value
							UpperCAmelCase_						=				np.pad(lowerCAmelCase    ,	((0, 0), (0, difference))    ,	"constant"    ,	constant_values=lowerCAmelCase     )

							UpperCAmelCase_						=				audio_values.tolist()
							for i in range(lowerCAmelCase     ):
									UpperCAmelCase_						=				np.asarray(audio_values[i]     )[
									    padding_mask[i][None, :] != self.feature_extractor.padding_value
									]
									UpperCAmelCase_						=				sliced_audio.reshape(lowerCAmelCase    ,	-1     )

							return audio_values






from typing import List, Union

from ..utils import (
    add_end_docstrings,
    is_tf_available,
    is_torch_available,
    is_vision_available,
    logging,
    requires_backends,
)
from .base import PIPELINE_INIT_ARGS, Pipeline


if is_vision_available():
			from PIL import Image

			from ..image_utils import load_image

if is_tf_available():
			from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_VISION_2_SEQ_MAPPING

if is_torch_available():
			import torch

			from ..models.auto.modeling_auto import MODEL_FOR_VISION_2_SEQ_MAPPING

SCREAMING_SNAKE_CASE     				=						logging.get_logger(__name__)



@add_end_docstrings(lowercase__  )
class 	lowerCamelCase      (						lowercase__  ):







					'''simple docstring'''







					def __init__(			self    ,	*lowerCAmelCase    ,	**lowerCAmelCase     ):
							super().__init__(*lowerCAmelCase    ,	**lowerCAmelCase     )
							requires_backends(self    ,	"vision"     )
							self.check_model_type(
							    TF_MODEL_FOR_VISION_2_SEQ_MAPPING if self.framework == "tf" else MODEL_FOR_VISION_2_SEQ_MAPPING     )



					def    A__		(			self    ,	lowerCAmelCase=None    ,	lowerCAmelCase=None    ,	lowerCAmelCase=None     ):
							UpperCAmelCase_						=				{}
							UpperCAmelCase_						=				{}

							if prompt is not None:
									UpperCAmelCase_						=				prompt

							if generate_kwargs is not None:
									UpperCAmelCase_						=				generate_kwargs
							if max_new_tokens is not None:
									if "generate_kwargs" not in forward_kwargs:
											UpperCAmelCase_						=				{}
									if "max_new_tokens" in forward_kwargs["generate_kwargs"]:
											raise ValueError(
											    "'max_new_tokens' is defined twice, once in 'generate_kwargs' and once as a direct parameter,"
											    " please use only one"     )
									UpperCAmelCase_						=				max_new_tokens
							return preprocess_params, forward_kwargs, {}



					def __call__(			self    ,	lowerCAmelCase    ,	**lowerCAmelCase     ):
							return super().__call__(lowerCAmelCase    ,	**lowerCAmelCase     )



					def    A__		(			self    ,	lowerCAmelCase    ,	lowerCAmelCase=None     ):
							UpperCAmelCase_						=				load_image(lowerCAmelCase     )

							if prompt is not None:
									if not isinstance(lowerCAmelCase    ,	lowerCAmelCase     ):
											raise ValueError(
											    f'''Received an invalid text input, got - {type(lowerCAmelCase     )} - but expected a single string. '''
											    "Note also that one single text can be provided for conditional image to text generation."     )

									UpperCAmelCase_						=				self.model.config.model_type

									if model_type == "git":
											UpperCAmelCase_						=				self.image_processor(images=lowerCAmelCase    ,	return_tensors=self.framework     )
											UpperCAmelCase_						=				self.tokenizer(text=lowerCAmelCase    ,	add_special_tokens=lowerCAmelCase     ).input_ids
											UpperCAmelCase_						=				[self.tokenizer.cls_token_id] + input_ids
											UpperCAmelCase_						=				torch.tensor(lowerCAmelCase     ).unsqueeze(0     )
											model_inputs.update({"input_ids": input_ids}     )

									elif model_type == "pix2struct":
											UpperCAmelCase_						=				self.image_processor(images=lowerCAmelCase    ,	header_text=lowerCAmelCase    ,	return_tensors=self.framework     )

									elif model_type != "vision-encoder-decoder":
											# vision-encoder-decoder does not support conditional generation
											UpperCAmelCase_						=				self.image_processor(images=lowerCAmelCase    ,	return_tensors=self.framework     )
											UpperCAmelCase_						=				self.tokenizer(lowerCAmelCase    ,	return_tensors=self.framework     )
											model_inputs.update(lowerCAmelCase     )

									else:
											raise ValueError(f'''Model type {model_type} does not support conditional text generation'''     )

							else:
									UpperCAmelCase_						=				self.image_processor(images=lowerCAmelCase    ,	return_tensors=self.framework     )

							if self.model.config.model_type == "git" and prompt is None:
									UpperCAmelCase_						=				None

							return model_inputs



					def    A__		(			self    ,	lowerCAmelCase    ,	lowerCAmelCase=None     ):
							# Git model sets `model_inputs["input_ids"] = None` in `preprocess` (when `prompt=None`). In batch model, the
							# pipeline will group them into a list of `None`, which fail `_forward`. Avoid this by checking it first.
							if (
							    "input_ids" in model_inputs
							    and isinstance(model_inputs["input_ids"]    ,	lowerCAmelCase     )
							    and all(x is None for x in model_inputs["input_ids"]     )
							):
									UpperCAmelCase_						=				None

							if generate_kwargs is None:
									UpperCAmelCase_						=				{}
							# FIXME: We need to pop here due to a difference in how `generation.py` and `generation.tf_utils.py`
							#  parse inputs. In the Tensorflow version, `generate` raises an error if we don't use `input_ids` whereas
							#  the PyTorch version matches it with `self.model.main_input_name` or `self.model.encoder.main_input_name`
							#  in the `_prepare_model_inputs` method.
							UpperCAmelCase_						=				model_inputs.pop(self.model.main_input_name     )
							UpperCAmelCase_						=				self.model.generate(lowerCAmelCase    ,	**lowerCAmelCase    ,	**lowerCAmelCase     )
							return model_outputs



					def    A__		(			self    ,	lowerCAmelCase     ):
							UpperCAmelCase_						=				[]
							for output_ids in model_outputs:
									UpperCAmelCase_						=				{
									    "generated_text": self.tokenizer.decode(
									        lowerCAmelCase    ,	skip_special_tokens=lowerCAmelCase    ,	)
									}
									records.append(lowerCAmelCase     )
							return records

